Removed obfuscatory 'access' macros: see issue#76

git-svn-id: https://tesseract-ocr.googlecode.com/svn/trunk@219 d0cd1f9f-072b-0410-8dd7-cf729c803f20
This commit is contained in:
theraysmith 2009-03-10 19:03:06 +00:00
parent 5c964ea6da
commit ff3d550c05
32 changed files with 648 additions and 971 deletions

View File

@ -85,7 +85,7 @@ void FreeTempConfig(TEMP_CONFIG Config) {
destroy_nodes (Config->ContextsSeen, memfree); destroy_nodes (Config->ContextsSeen, memfree);
FreeBitVector (Config->Protos); FreeBitVector (Config->Protos);
c_free_struct (Config, sizeof (TEMP_CONFIG_STRUCT), "TEMP_CONFIG_STRUCT"); free_struct (Config, sizeof (TEMP_CONFIG_STRUCT), "TEMP_CONFIG_STRUCT");
} /* FreeTempConfig */ } /* FreeTempConfig */
@ -94,7 +94,7 @@ void FreeTempConfig(TEMP_CONFIG Config) {
void FreeTempProto(void *arg) { void FreeTempProto(void *arg) {
PROTO proto = (PROTO) arg; PROTO proto = (PROTO) arg;
c_free_struct (proto, sizeof (TEMP_PROTO_STRUCT), "TEMP_PROTO_STRUCT"); free_struct (proto, sizeof (TEMP_PROTO_STRUCT), "TEMP_PROTO_STRUCT");
} }
@ -174,12 +174,12 @@ ADAPT_TEMPLATES NewAdaptedTemplates() {
} /* NewAdaptedTemplates */ } /* NewAdaptedTemplates */
/*-------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void free_adapted_templates(ADAPT_TEMPLATES templates) { void free_adapted_templates(ADAPT_TEMPLATES templates) {
if (templates != NULL) { if (templates != NULL) {
int i; int i;
for (i = 0; i < NumClassesIn (templates->Templates); i++) for (i = 0; i < (templates->Templates)->NumClasses; i++)
free_adapted_class (templates->Class[i]); free_adapted_class (templates->Class[i]);
free_int_templates (templates->Templates); free_int_templates (templates->Templates);
Efree(templates); Efree(templates);
@ -203,7 +203,7 @@ TEMP_CONFIG NewTempConfig(int MaxProtoId) {
int NumProtos = MaxProtoId + 1; int NumProtos = MaxProtoId + 1;
Config = Config =
(TEMP_CONFIG) c_alloc_struct (sizeof (TEMP_CONFIG_STRUCT), (TEMP_CONFIG) alloc_struct (sizeof (TEMP_CONFIG_STRUCT),
"TEMP_CONFIG_STRUCT"); "TEMP_CONFIG_STRUCT");
Config->Protos = NewBitVector (NumProtos); Config->Protos = NewBitVector (NumProtos);
@ -229,7 +229,7 @@ TEMP_PROTO NewTempProto() {
** History: Thu Mar 14 13:31:31 1991, DSJ, Created. ** History: Thu Mar 14 13:31:31 1991, DSJ, Created.
*/ */
return ((TEMP_PROTO) return ((TEMP_PROTO)
c_alloc_struct (sizeof (TEMP_PROTO_STRUCT), "TEMP_PROTO_STRUCT")); alloc_struct (sizeof (TEMP_PROTO_STRUCT), "TEMP_PROTO_STRUCT"));
} /* NewTempProto */ } /* NewTempProto */
@ -253,19 +253,19 @@ void PrintAdaptedTemplates(FILE *File, ADAPT_TEMPLATES Templates) {
#ifndef SECURE_NAMES #ifndef SECURE_NAMES
fprintf (File, "\n\nSUMMARY OF ADAPTED TEMPLATES:\n\n"); fprintf (File, "\n\nSUMMARY OF ADAPTED TEMPLATES:\n\n");
fprintf (File, "Num classes = %d; Num permanent classes = %d\n\n", fprintf (File, "Num classes = %d; Num permanent classes = %d\n\n",
NumClassesIn (Templates->Templates), Templates->NumPermClasses); (Templates->Templates)->NumClasses, Templates->NumPermClasses);
fprintf (File, "Index Id NC NPC NP NPP\n"); fprintf (File, "Index Id NC NPC NP NPP\n");
fprintf (File, "------------------------\n"); fprintf (File, "------------------------\n");
for (i = 0; i < NumClassesIn (Templates->Templates); i++) { for (i = 0; i < (Templates->Templates)->NumClasses; i++) {
IClass = ClassForIndex (Templates->Templates, i); IClass = Templates->Templates->Class[i];
AClass = Templates->Class[i]; AClass = Templates->Class[i];
fprintf (File, "%5d %s %3d %3d %3d %3d\n", fprintf (File, "%5d %s %3d %3d %3d %3d\n",
i, unicharset.id_to_unichar(ClassIdForIndex (Templates->Templates, i)), i, unicharset.id_to_unichar(Templates->Templates->ClassIdFor[i]),
NumIntConfigsIn (IClass), AClass->NumPermConfigs, IClass->NumConfigs, AClass->NumPermConfigs,
NumIntProtosIn (IClass), IClass->NumProtos,
NumIntProtosIn (IClass) - count (AClass->TempProtos)); IClass->NumProtos - count (AClass->TempProtos));
} }
#endif #endif
fprintf (File, "\n"); fprintf (File, "\n");
@ -308,7 +308,7 @@ ADAPT_CLASS ReadAdaptedClass(FILE *File) {
Class->TempProtos = NIL; Class->TempProtos = NIL;
for (i = 0; i < NumTempProtos; i++) { for (i = 0; i < NumTempProtos; i++) {
TempProto = TempProto =
(TEMP_PROTO) c_alloc_struct (sizeof (TEMP_PROTO_STRUCT), (TEMP_PROTO) alloc_struct (sizeof (TEMP_PROTO_STRUCT),
"TEMP_PROTO_STRUCT"); "TEMP_PROTO_STRUCT");
fread ((char *) TempProto, sizeof (TEMP_PROTO_STRUCT), 1, File); fread ((char *) TempProto, sizeof (TEMP_PROTO_STRUCT), 1, File);
Class->TempProtos = push_last (Class->TempProtos, TempProto); Class->TempProtos = push_last (Class->TempProtos, TempProto);
@ -350,7 +350,7 @@ ADAPT_TEMPLATES ReadAdaptedTemplates(FILE *File) {
Templates->Templates = ReadIntTemplates (File, FALSE); Templates->Templates = ReadIntTemplates (File, FALSE);
/* then read in the adaptive info for each class */ /* then read in the adaptive info for each class */
for (i = 0; i < NumClassesIn (Templates->Templates); i++) { for (i = 0; i < (Templates->Templates)->NumClasses; i++) {
Templates->Class[i] = ReadAdaptedClass (File); Templates->Class[i] = ReadAdaptedClass (File);
} }
return (Templates); return (Templates);
@ -398,7 +398,7 @@ TEMP_CONFIG ReadTempConfig(FILE *File) {
TEMP_CONFIG Config; TEMP_CONFIG Config;
Config = Config =
(TEMP_CONFIG) c_alloc_struct (sizeof (TEMP_CONFIG_STRUCT), (TEMP_CONFIG) alloc_struct (sizeof (TEMP_CONFIG_STRUCT),
"TEMP_CONFIG_STRUCT"); "TEMP_CONFIG_STRUCT");
fread ((char *) Config, sizeof (TEMP_CONFIG_STRUCT), 1, File); fread ((char *) Config, sizeof (TEMP_CONFIG_STRUCT), 1, File);
@ -479,10 +479,9 @@ void WriteAdaptedTemplates(FILE *File, ADAPT_TEMPLATES Templates) {
WriteIntTemplates (File, Templates->Templates, unicharset); WriteIntTemplates (File, Templates->Templates, unicharset);
/* then write out the adaptive info for each class */ /* then write out the adaptive info for each class */
for (i = 0; i < NumClassesIn (Templates->Templates); i++) { for (i = 0; i < (Templates->Templates)->NumClasses; i++) {
WriteAdaptedClass (File, Templates->Class[i], WriteAdaptedClass (File, Templates->Class[i],
NumIntConfigsIn (ClassForIndex Templates->Templates->Class[i]->NumConfigs);
(Templates->Templates, i)));
} }
} /* WriteAdaptedTemplates */ } /* WriteAdaptedTemplates */

View File

@ -235,195 +235,6 @@ void ShowBestMatchFor(TBLOB *Blob,
BOOL8 AdaptiveOn, BOOL8 AdaptiveOn,
BOOL8 PreTrainedOn); BOOL8 PreTrainedOn);
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* /users/danj/wiseowl/src/danj/microfeatures/adaptmatch.c
int AdaptableWord
_ARGS((TWERD *Word,
char *BestChoice,
char *BestRawChoice));
void AdaptToChar
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID ClassId,
FLOAT32 Threshold));
void AdaptToPunc
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID ClassId,
FLOAT32 Threshold));
void AddNewResult
_ARGS((ADAPT_RESULTS *Results,
CLASS_ID ClassId,
FLOAT32 Rating,
int ConfigId));
void AmbigClassifier
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
INT_TEMPLATES Templates,
char *Ambiguities,
ADAPT_RESULTS *Results));
char *BaselineClassifier
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
ADAPT_TEMPLATES Templates,
ADAPT_RESULTS *Results));
void CharNormClassifier
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
INT_TEMPLATES Templates,
ADAPT_RESULTS *Results));
void ClassifyAsNoise
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
ADAPT_RESULTS *Results));
int CompareCurrentRatings
_ARGS((CLASS_ID *Class1,
CLASS_ID *Class2));
LIST ConvertMatchesToChoices
_ARGS((ADAPT_RESULTS *Results));
void DebugAdaptiveClassifier
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
ADAPT_RESULTS *Results));
void DoAdaptiveMatch
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
ADAPT_RESULTS *Results));
void GetAdaptThresholds
_ARGS((TWERD *Word,
LINE_STATS *LineStats,
char *BestChoice,
char *BestRawChoice,
FLOAT32 Thresholds []));
int GetAdaptiveFeatures
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
INT_FEATURE_ARRAY IntFeatures,
CHAR_DESC *FloatFeatures));
char *GetAmbiguities
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID CorrectClass));
int GetBaselineFeatures
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
INT_TEMPLATES Templates,
INT_FEATURE_ARRAY IntFeatures,
CLASS_NORMALIZATION_ARRAY CharNormArray,
FLOAT32 *BlobLength));
FLOAT32 GetBestRatingFor
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID ClassId));
int GetCharNormFeatures
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
INT_TEMPLATES Templates,
INT_FEATURE_ARRAY IntFeatures,
CLASS_NORMALIZATION_ARRAY CharNormArray,
FLOAT32 *BlobLength));
int GetIntBaselineFeatures
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
INT_TEMPLATES Templates,
INT_FEATURE_ARRAY IntFeatures,
CLASS_NORMALIZATION_ARRAY CharNormArray,
FLOAT32 *BlobLength));
int GetIntCharNormFeatures
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
INT_TEMPLATES Templates,
INT_FEATURE_ARRAY IntFeatures,
CLASS_NORMALIZATION_ARRAY CharNormArray,
FLOAT32 *BlobLength));
void InitMatcherRatings
_ARGS((FLOAT32 *Rating));
void MakeNewAdaptedClass
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID ClassId,
ADAPT_TEMPLATES Templates));
void MakeNewTemporaryConfig
_ARGS((ADAPT_TEMPLATES Templates,
CLASS_ID ClassId,
int NumFeatures,
INT_FEATURE_ARRAY Features,
FEATURE_SET FloatFeatures));
PROTO_ID MakeNewTempProtos
_ARGS((FEATURE_SET Features,
int NumBadFeat,
FEATURE_ID BadFeat [],
INT_CLASS IClass,
ADAPT_CLASS Class,
BIT_VECTOR TempProtoMask));
void MakePermanent
_ARGS((ADAPT_TEMPLATES Templates,
CLASS_ID ClassId,
int ConfigId,
BLOB *Blob,
LINE_STATS *LineStats));
int MakeTempProtoPerm
_ARGS((TEMP_PROTO TempProto,
PROTO_KEY *ProtoKey));
int NumBlobsIn
_ARGS((TWERD *Word));
int NumOutlinesInBlob
_ARGS((BLOB *Blob));
void PrintAdaptiveMatchResults
_ARGS((FILE *File,
ADAPT_RESULTS *Results));
void RemoveBadMatches
_ARGS((ADAPT_RESULTS *Results));
void RemoveExtraPuncs
_ARGS((ADAPT_RESULTS *Results));
void SetAdaptiveThreshold
_ARGS((FLOAT32 Threshold));
void ShowBestMatchFor
_ARGS((BLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID ClassId,
BOOL8 AdaptiveOn,
BOOL8 PreTrainedOn));
#undef _ARGS
*/
/**---------------------------------------------------------------------------- /**----------------------------------------------------------------------------
Global Data Definitions and Declarations Global Data Definitions and Declarations
@ -894,17 +705,17 @@ void InitAdaptiveClassifier() {
InitIntegerMatcher(); InitIntegerMatcher();
InitIntegerFX(); InitIntegerFX();
AllProtosOn = NewBitVector (MAX_NUM_PROTOS); AllProtosOn = NewBitVector(MAX_NUM_PROTOS);
PrunedProtos = NewBitVector (MAX_NUM_PROTOS); PrunedProtos = NewBitVector(MAX_NUM_PROTOS);
AllConfigsOn = NewBitVector (MAX_NUM_CONFIGS); AllConfigsOn = NewBitVector(MAX_NUM_CONFIGS);
AllProtosOff = NewBitVector (MAX_NUM_PROTOS); AllProtosOff = NewBitVector(MAX_NUM_PROTOS);
AllConfigsOff = NewBitVector (MAX_NUM_CONFIGS); AllConfigsOff = NewBitVector(MAX_NUM_CONFIGS);
TempProtoMask = NewBitVector (MAX_NUM_PROTOS); TempProtoMask = NewBitVector(MAX_NUM_PROTOS);
set_all_bits (AllProtosOn, WordsInVectorOfSize (MAX_NUM_PROTOS)); set_all_bits(AllProtosOn, WordsInVectorOfSize(MAX_NUM_PROTOS));
set_all_bits (PrunedProtos, WordsInVectorOfSize (MAX_NUM_PROTOS)); set_all_bits(PrunedProtos, WordsInVectorOfSize(MAX_NUM_PROTOS));
set_all_bits (AllConfigsOn, WordsInVectorOfSize (MAX_NUM_CONFIGS)); set_all_bits(AllConfigsOn, WordsInVectorOfSize(MAX_NUM_CONFIGS));
zero_all_bits (AllProtosOff, WordsInVectorOfSize (MAX_NUM_PROTOS)); zero_all_bits(AllProtosOff, WordsInVectorOfSize(MAX_NUM_PROTOS));
zero_all_bits (AllConfigsOff, WordsInVectorOfSize (MAX_NUM_CONFIGS)); zero_all_bits(AllConfigsOff, WordsInVectorOfSize(MAX_NUM_CONFIGS));
if (UsePreAdaptedTemplates) { if (UsePreAdaptedTemplates) {
Filename = imagefile; Filename = imagefile;
@ -922,12 +733,10 @@ void InitAdaptiveClassifier() {
fclose(File); fclose(File);
PrintAdaptedTemplates(stdout, AdaptedTemplates); PrintAdaptedTemplates(stdout, AdaptedTemplates);
for (i = 0; i < NumClassesIn (AdaptedTemplates->Templates); i++) { for (i = 0; i < (AdaptedTemplates->Templates)->NumClasses; i++) {
BaselineCutoffs[i] = BaselineCutoffs[i] =
CharNormCutoffs[IndexForClassId (PreTrainedTemplates, CharNormCutoffs[PreTrainedTemplates->IndexFor[
ClassIdForIndex AdaptedTemplates->Templates->ClassIdFor[i]]];
(AdaptedTemplates->Templates,
i))];
} }
} }
} else { } else {
@ -1123,7 +932,7 @@ void MakeNewAdaptedClass(TBLOB *Blob,
NormMethod = baseline; NormMethod = baseline;
Features = ExtractOutlineFeatures (Blob, LineStats); Features = ExtractOutlineFeatures (Blob, LineStats);
NumFeatures = NumFeaturesIn (Features); NumFeatures = Features->NumFeatures;
if (NumFeatures > UNLIKELY_NUM_FEAT) { if (NumFeatures > UNLIKELY_NUM_FEAT) {
FreeFeatureSet(Features); FreeFeatureSet(Features);
return; return;
@ -1137,25 +946,25 @@ void MakeNewAdaptedClass(TBLOB *Blob,
/* this is a kludge to construct cutoffs for adapted templates */ /* this is a kludge to construct cutoffs for adapted templates */
if (Templates == AdaptedTemplates) if (Templates == AdaptedTemplates)
BaselineCutoffs[ClassIndex] = BaselineCutoffs[ClassIndex] =
CharNormCutoffs[IndexForClassId (PreTrainedTemplates, ClassId)]; CharNormCutoffs[PreTrainedTemplates->IndexFor[ClassId]];
IClass = ClassForClassId (Templates->Templates, ClassId); IClass = ClassForClassId (Templates->Templates, ClassId);
for (Fid = 0; Fid < NumFeaturesIn (Features); Fid++) { for (Fid = 0; Fid < Features->NumFeatures; Fid++) {
Pid = AddIntProto (IClass); Pid = AddIntProto (IClass);
assert (Pid != NO_PROTO); assert (Pid != NO_PROTO);
Feature = FeatureIn (Features, Fid); Feature = Features->Features[Fid];
TempProto = NewTempProto (); TempProto = NewTempProto ();
Proto = &(TempProto->Proto); Proto = &(TempProto->Proto);
/* compute proto params - NOTE that Y_DIM_OFFSET must be used because /* compute proto params - NOTE that Y_DIM_OFFSET must be used because
ConvertProto assumes that the Y dimension varies from -0.5 to 0.5 ConvertProto assumes that the Y dimension varies from -0.5 to 0.5
instead of the -0.25 to 0.75 used in baseline normalization */ instead of the -0.25 to 0.75 used in baseline normalization */
ProtoAngle (Proto) = ParamOf (Feature, OutlineFeatDir); Proto->Angle = Feature->Params[OutlineFeatDir];
ProtoX (Proto) = ParamOf (Feature, OutlineFeatX); Proto->X = Feature->Params[OutlineFeatX];
ProtoY (Proto) = ParamOf (Feature, OutlineFeatY) - Y_DIM_OFFSET; Proto->Y = Feature->Params[OutlineFeatY] - Y_DIM_OFFSET;
ProtoLength (Proto) = ParamOf (Feature, OutlineFeatLength); Proto->Length = Feature->Params[OutlineFeatLength];
FillABC(Proto); FillABC(Proto);
TempProto->ProtoId = Pid; TempProto->ProtoId = Pid;
@ -1209,7 +1018,7 @@ int GetAdaptiveFeatures(TBLOB *Blob,
NormMethod = baseline; NormMethod = baseline;
Features = ExtractPicoFeatures (Blob, LineStats); Features = ExtractPicoFeatures (Blob, LineStats);
NumFeatures = NumFeaturesIn (Features); NumFeatures = Features->NumFeatures;
if (NumFeatures > UNLIKELY_NUM_FEAT) { if (NumFeatures > UNLIKELY_NUM_FEAT) {
FreeFeatureSet(Features); FreeFeatureSet(Features);
return (0); return (0);
@ -1328,7 +1137,7 @@ void AdaptToChar(TBLOB *Blob,
} }
else { else {
IClass = ClassForClassId (AdaptedTemplates->Templates, ClassId); IClass = ClassForClassId (AdaptedTemplates->Templates, ClassId);
ClassIndex = IndexForClassId (AdaptedTemplates->Templates, ClassId); ClassIndex = AdaptedTemplates->Templates->IndexFor[ClassId];
Class = AdaptedTemplates->Class[ClassIndex]; Class = AdaptedTemplates->Class[ClassIndex];
NumFeatures = GetAdaptiveFeatures (Blob, LineStats, NumFeatures = GetAdaptiveFeatures (Blob, LineStats,
@ -1496,7 +1305,7 @@ void AddNewResult(ADAPT_RESULTS *Results,
Results->Ratings[ClassId] = Rating; Results->Ratings[ClassId] = Rating;
if (ClassId != NO_CLASS) if (ClassId != NO_CLASS)
CharClass = ClassForClassId(PreTrainedTemplates, ClassId); CharClass = ClassForClassId(PreTrainedTemplates, ClassId);
if (CharClass != NULL && NumIntConfigsIn(CharClass) == 32) if (CharClass != NULL && CharClass->NumConfigs == 32)
Results->Configs[ClassId] = ConfigId; Results->Configs[ClassId] = ConfigId;
else else
Results->Configs[ClassId] = ~0; Results->Configs[ClassId] = ~0;
@ -1566,7 +1375,7 @@ void AmbigClassifier(TBLOB *Blob,
while (*Ambiguities >= 0) { while (*Ambiguities >= 0) {
ClassId = *Ambiguities; ClassId = *Ambiguities;
ClassIndex = IndexForClassId (Templates, ClassId); ClassIndex = Templates->IndexFor[ClassId];
SetCharNormMatch(); SetCharNormMatch();
IntegerMatcher (ClassForClassId (Templates, ClassId), IntegerMatcher (ClassForClassId (Templates, ClassId),
@ -1605,7 +1414,7 @@ void MasterMatcher(INT_TEMPLATES templates,
for (int c = 0; c < num_classes; c++) { for (int c = 0; c < num_classes; c++) {
CLASS_ID class_id = results[c].Class; CLASS_ID class_id = results[c].Class;
INT_RESULT_STRUCT& int_result = results[c].IMResult; INT_RESULT_STRUCT& int_result = results[c].IMResult;
CLASS_INDEX class_index = IndexForClassId(templates, class_id); CLASS_INDEX class_index = templates->IndexFor[class_id];
BIT_VECTOR protos = classes != NULL ? classes[class_index]->PermProtos BIT_VECTOR protos = classes != NULL ? classes[class_index]->PermProtos
: AllProtosOn; : AllProtosOn;
BIT_VECTOR configs = classes != NULL ? classes[class_index]->PermConfigs BIT_VECTOR configs = classes != NULL ? classes[class_index]->PermConfigs
@ -1698,7 +1507,7 @@ UNICHAR_ID *BaselineClassifier(TBLOB *Blob,
return (NULL); return (NULL);
/* this is a bug - maybe should return "" */ /* this is a bug - maybe should return "" */
ClassIndex = IndexForClassId (Templates->Templates, ClassId); ClassIndex = Templates->Templates->IndexFor[ClassId];
return (Templates->Class[ClassIndex]-> return (Templates->Class[ClassIndex]->
Config[Results->BestConfig].Perm); Config[Results->BestConfig].Perm);
} /* BaselineClassifier */ } /* BaselineClassifier */
@ -2198,7 +2007,7 @@ void DoAdaptiveMatch(TBLOB *Blob,
NormMethod = baseline; NormMethod = baseline;
Features = ExtractPicoFeatures (Blob, LineStats); Features = ExtractPicoFeatures (Blob, LineStats);
NumFeatures = NumFeaturesIn (Features); NumFeatures = Features->NumFeatures;
*BlobLength = NumFeatures; *BlobLength = NumFeatures;
if (NumFeatures > UNLIKELY_NUM_FEAT) { if (NumFeatures > UNLIKELY_NUM_FEAT) {
FreeFeatureSet(Features); FreeFeatureSet(Features);
@ -2258,7 +2067,7 @@ void DoAdaptiveMatch(TBLOB *Blob,
PreTrainedTemplates, PreTrainedTemplates,
CNFeatures, CNAdjust, &BlobLength); CNFeatures, CNAdjust, &BlobLength);
if (NumCNFeatures > 0) { if (NumCNFeatures > 0) {
ClassIndex = IndexForClassId (PreTrainedTemplates, ClassId); ClassIndex = PreTrainedTemplates->IndexFor[ClassId];
SetCharNormMatch(); SetCharNormMatch();
IntegerMatcher (ClassForClassId (PreTrainedTemplates, ClassId), IntegerMatcher (ClassForClassId (PreTrainedTemplates, ClassId),
@ -2273,7 +2082,7 @@ void DoAdaptiveMatch(TBLOB *Blob,
AdaptedTemplates->Templates, AdaptedTemplates->Templates,
BLFeatures, BLAdjust, &BlobLength); BLFeatures, BLAdjust, &BlobLength);
if (NumBLFeatures > 0) { if (NumBLFeatures > 0) {
ClassIndex = IndexForClassId (AdaptedTemplates->Templates, ClassId); ClassIndex = AdaptedTemplates->Templates->IndexFor[ClassId];
SetBaseLineMatch(); SetBaseLineMatch();
IntegerMatcher (ClassForClassId IntegerMatcher (ClassForClassId
@ -2452,11 +2261,11 @@ void DoAdaptiveMatch(TBLOB *Blob,
NormFeature = NewFeature (&CharNormDesc); NormFeature = NewFeature (&CharNormDesc);
Baseline = BaselineAt (LineStats, FXInfo.Xmean); Baseline = BaselineAt (LineStats, FXInfo.Xmean);
Scale = ComputeScaleFactor (LineStats); Scale = ComputeScaleFactor (LineStats);
ParamOf (NormFeature, CharNormY) = (FXInfo.Ymean - Baseline) * Scale; NormFeature->Params[CharNormY] = (FXInfo.Ymean - Baseline) * Scale;
ParamOf (NormFeature, CharNormLength) = NormFeature->Params[CharNormLength] =
FXInfo.Length * Scale / LENGTH_COMPRESSION; FXInfo.Length * Scale / LENGTH_COMPRESSION;
ParamOf (NormFeature, CharNormRx) = FXInfo.Rx * Scale; NormFeature->Params[CharNormRx] = FXInfo.Rx * Scale;
ParamOf (NormFeature, CharNormRy) = FXInfo.Ry * Scale; NormFeature->Params[CharNormRy] = FXInfo.Ry * Scale;
ComputeIntCharNormArray(NormFeature, Templates, CharNormArray); ComputeIntCharNormArray(NormFeature, Templates, CharNormArray);
FreeFeature(NormFeature); FreeFeature(NormFeature);
@ -2536,11 +2345,11 @@ void DoAdaptiveMatch(TBLOB *Blob,
debug_level = debug_level =
PRINT_MATCH_SUMMARY | PRINT_FEATURE_MATCHES | PRINT_PROTO_MATCHES; PRINT_MATCH_SUMMARY | PRINT_FEATURE_MATCHES | PRINT_PROTO_MATCHES;
ClassIndex = IndexForClassId (Templates->Templates, ClassId); ClassIndex = Templates->Templates->IndexFor[ClassId];
IClass = ClassForClassId (Templates->Templates, ClassId); IClass = ClassForClassId (Templates->Templates, ClassId);
Class = Templates->Class[ClassIndex]; Class = Templates->Class[ClassIndex];
if (NumIntConfigsIn (IClass) >= MAX_NUM_CONFIGS) if (IClass->NumConfigs >= MAX_NUM_CONFIGS)
{ {
++NumAdaptationsFailed; ++NumAdaptationsFailed;
if (LearningDebugLevel >= 1) if (LearningDebugLevel >= 1)
@ -2548,7 +2357,7 @@ void DoAdaptiveMatch(TBLOB *Blob,
return -1; return -1;
} }
OldMaxProtoId = NumIntProtosIn (IClass) - 1; OldMaxProtoId = IClass->NumProtos - 1;
NumOldProtos = FindGoodProtos (IClass, AllProtosOn, AllConfigsOff, NumOldProtos = FindGoodProtos (IClass, AllProtosOn, AllConfigsOff,
BlobLength, NumFeatures, Features, BlobLength, NumFeatures, Features,
@ -2630,19 +2439,19 @@ void DoAdaptiveMatch(TBLOB *Blob,
for (ProtoStart = BadFeat, LastBad = ProtoStart + NumBadFeat; for (ProtoStart = BadFeat, LastBad = ProtoStart + NumBadFeat;
ProtoStart < LastBad; ProtoStart = ProtoEnd) { ProtoStart < LastBad; ProtoStart = ProtoEnd) {
F1 = FeatureIn (Features, *ProtoStart); F1 = Features->Features[*ProtoStart];
X1 = ParamOf (F1, PicoFeatX); X1 = F1->Params[PicoFeatX];
Y1 = ParamOf (F1, PicoFeatY); Y1 = F1->Params[PicoFeatY];
A1 = ParamOf (F1, PicoFeatDir); A1 = F1->Params[PicoFeatDir];
for (ProtoEnd = ProtoStart + 1, for (ProtoEnd = ProtoStart + 1,
SegmentLength = GetPicoFeatureLength (); SegmentLength = GetPicoFeatureLength ();
ProtoEnd < LastBad; ProtoEnd < LastBad;
ProtoEnd++, SegmentLength += GetPicoFeatureLength ()) { ProtoEnd++, SegmentLength += GetPicoFeatureLength ()) {
F2 = FeatureIn (Features, *ProtoEnd); F2 = Features->Features[*ProtoEnd];
X2 = ParamOf (F2, PicoFeatX); X2 = F2->Params[PicoFeatX];
Y2 = ParamOf (F2, PicoFeatY); Y2 = F2->Params[PicoFeatY];
A2 = ParamOf (F2, PicoFeatDir); A2 = F2->Params[PicoFeatDir];
AngleDelta = fabs (A1 - A2); AngleDelta = fabs (A1 - A2);
if (AngleDelta > 0.5) if (AngleDelta > 0.5)
@ -2654,10 +2463,10 @@ void DoAdaptiveMatch(TBLOB *Blob,
break; break;
} }
F2 = FeatureIn (Features, *(ProtoEnd - 1)); F2 = Features->Features[*(ProtoEnd - 1)];
X2 = ParamOf (F2, PicoFeatX); X2 = F2->Params[PicoFeatX];
Y2 = ParamOf (F2, PicoFeatY); Y2 = F2->Params[PicoFeatY];
A2 = ParamOf (F2, PicoFeatDir); A2 = F2->Params[PicoFeatDir];
Pid = AddIntProto (IClass); Pid = AddIntProto (IClass);
if (Pid == NO_PROTO) if (Pid == NO_PROTO)
@ -2669,10 +2478,10 @@ void DoAdaptiveMatch(TBLOB *Blob,
/* compute proto params - NOTE that Y_DIM_OFFSET must be used because /* compute proto params - NOTE that Y_DIM_OFFSET must be used because
ConvertProto assumes that the Y dimension varies from -0.5 to 0.5 ConvertProto assumes that the Y dimension varies from -0.5 to 0.5
instead of the -0.25 to 0.75 used in baseline normalization */ instead of the -0.25 to 0.75 used in baseline normalization */
ProtoLength (Proto) = SegmentLength; Proto->Length = SegmentLength;
ProtoAngle (Proto) = A1; Proto->Angle = A1;
ProtoX (Proto) = (X1 + X2) / 2.0; Proto->X = (X1 + X2) / 2.0;
ProtoY (Proto) = (Y1 + Y2) / 2.0 - Y_DIM_OFFSET; Proto->Y = (Y1 + Y2) / 2.0 - Y_DIM_OFFSET;
FillABC(Proto); FillABC(Proto);
TempProto->ProtoId = Pid; TempProto->ProtoId = Pid;
@ -2683,7 +2492,7 @@ void DoAdaptiveMatch(TBLOB *Blob,
Class->TempProtos = push (Class->TempProtos, TempProto); Class->TempProtos = push (Class->TempProtos, TempProto);
} }
return (NumIntProtosIn (IClass) - 1); return (IClass->NumProtos - 1);
} /* MakeNewTempProtos */ } /* MakeNewTempProtos */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -2716,7 +2525,7 @@ void DoAdaptiveMatch(TBLOB *Blob,
ADAPT_CLASS Class; ADAPT_CLASS Class;
PROTO_KEY ProtoKey; PROTO_KEY ProtoKey;
ClassIndex = IndexForClassId (Templates->Templates, ClassId); ClassIndex = Templates->Templates->IndexFor[ClassId];
Class = Templates->Class[ClassIndex]; Class = Templates->Class[ClassIndex];
Config = TempConfigFor (Class, ConfigId); Config = TempConfigFor (Class, ConfigId);
@ -2772,8 +2581,7 @@ void DoAdaptiveMatch(TBLOB *Blob,
TempProto = (TEMP_PROTO) item1; TempProto = (TEMP_PROTO) item1;
ProtoKey = (PROTO_KEY *) item2; ProtoKey = (PROTO_KEY *) item2;
ClassIndex = IndexForClassId (ProtoKey->Templates->Templates, ClassIndex = ProtoKey->Templates->Templates->IndexFor[ProtoKey->ClassId];
ProtoKey->ClassId);
Class = ProtoKey->Templates->Class[ClassIndex]; Class = ProtoKey->Templates->Class[ClassIndex];
Config = TempConfigFor (Class, ProtoKey->ConfigId); Config = TempConfigFor (Class, ProtoKey->ConfigId);
@ -3064,7 +2872,7 @@ void DoAdaptiveMatch(TBLOB *Blob,
if (NumCNFeatures <= 0) if (NumCNFeatures <= 0)
cprintf ("Illegal blob (char norm features)!\n"); cprintf ("Illegal blob (char norm features)!\n");
else { else {
ClassIndex = IndexForClassId (PreTrainedTemplates, ClassId); ClassIndex = PreTrainedTemplates->IndexFor[ClassId];
SetCharNormMatch(); SetCharNormMatch();
IntegerMatcher (ClassForClassId (PreTrainedTemplates, ClassId), IntegerMatcher (ClassForClassId (PreTrainedTemplates, ClassId),
@ -3090,8 +2898,7 @@ void DoAdaptiveMatch(TBLOB *Blob,
if (NumBLFeatures <= 0) if (NumBLFeatures <= 0)
cprintf ("Illegal blob (baseline features)!\n"); cprintf ("Illegal blob (baseline features)!\n");
else { else {
ClassIndex = ClassIndex =AdaptedTemplates->Templates->IndexFor[ClassId];
IndexForClassId (AdaptedTemplates->Templates, ClassId);
SetBaseLineMatch(); SetBaseLineMatch();
IntegerMatcher (ClassForClassId IntegerMatcher (ClassForClassId
@ -3103,7 +2910,7 @@ void DoAdaptiveMatch(TBLOB *Blob,
BLAdjust[ClassIndex], &BLResult, NO_DEBUG); BLAdjust[ClassIndex], &BLResult, NO_DEBUG);
#ifndef SECURE_NAMES #ifndef SECURE_NAMES
int ClassIndex = IndexForClassId (AdaptedTemplates->Templates, ClassId); int ClassIndex = AdaptedTemplates->Templates->IndexFor[ClassId];
ADAPT_CLASS Class = AdaptedTemplates->Class[ClassIndex]; ADAPT_CLASS Class = AdaptedTemplates->Class[ClassIndex];
cprintf ("Best adaptive template match is config %2d (%4.1f) %s\n", cprintf ("Best adaptive template match is config %2d (%4.1f) %s\n",
BLResult.Config, BLResult.Rating * 100.0, BLResult.Config, BLResult.Rating * 100.0,
@ -3115,7 +2922,7 @@ void DoAdaptiveMatch(TBLOB *Blob,
cprintf ("\n"); cprintf ("\n");
if (BLResult.Rating < CNResult.Rating) { if (BLResult.Rating < CNResult.Rating) {
ClassIndex = IndexForClassId (AdaptedTemplates->Templates, ClassId); ClassIndex = AdaptedTemplates->Templates->IndexFor[ClassId];
if (next_config < 0) { if (next_config < 0) {
ConfigMask = 1 << BLResult.Config; ConfigMask = 1 << BLResult.Config;
next_config = 0; next_config = 0;
@ -3136,7 +2943,7 @@ void DoAdaptiveMatch(TBLOB *Blob,
BLResult.Config, BLResult.Rating * 100.0); BLResult.Config, BLResult.Rating * 100.0);
} }
else { else {
ClassIndex = IndexForClassId (PreTrainedTemplates, ClassId); ClassIndex = PreTrainedTemplates->IndexFor[ClassId];
ConfigMask = 1 << CNResult.Config; ConfigMask = 1 << CNResult.Config;
NormMethod = character; NormMethod = character;

View File

@ -116,8 +116,8 @@ void FreeCharDescription(CHAR_DESC CharDesc) {
int i; int i;
if (CharDesc) { if (CharDesc) {
for (i = 0; i < NumFeatureSetsIn (CharDesc); i++) for (i = 0; i < CharDesc->NumFeatureSets; i++)
FreeFeatureSet (FeaturesOfType (CharDesc, i)); FreeFeatureSet (CharDesc->FeatureSets[i]);
Efree(CharDesc); Efree(CharDesc);
} }
} /* FreeCharDescription */ } /* FreeCharDescription */
@ -138,10 +138,10 @@ CHAR_DESC NewCharDescription() {
int i; int i;
CharDesc = (CHAR_DESC) Emalloc (sizeof (CHAR_DESC_STRUCT)); CharDesc = (CHAR_DESC) Emalloc (sizeof (CHAR_DESC_STRUCT));
NumFeatureSetsIn (CharDesc) = NumFeaturesDefined (); CharDesc->NumFeatureSets = FeatureDefs.NumFeatureTypes;
for (i = 0; i < NumFeatureSetsIn (CharDesc); i++) for (i = 0; i < CharDesc->NumFeatureSets; i++)
FeaturesOfType (CharDesc, i) = NULL; CharDesc->FeatureSets[i] = NULL;
return (CharDesc); return (CharDesc);
@ -169,15 +169,15 @@ void WriteCharDescription(FILE *File, CHAR_DESC CharDesc) {
int Type; int Type;
int NumSetsToWrite = 0; int NumSetsToWrite = 0;
for (Type = 0; Type < NumFeatureSetsIn (CharDesc); Type++) for (Type = 0; Type < CharDesc->NumFeatureSets; Type++)
if (FeaturesOfType (CharDesc, Type)) if (CharDesc->FeatureSets[Type])
NumSetsToWrite++; NumSetsToWrite++;
fprintf (File, " %d\n", NumSetsToWrite); fprintf (File, " %d\n", NumSetsToWrite);
for (Type = 0; Type < NumFeatureSetsIn (CharDesc); Type++) for (Type = 0; Type < CharDesc->NumFeatureSets; Type++)
if (FeaturesOfType (CharDesc, Type)) { if (CharDesc->FeatureSets[Type]) {
fprintf (File, "%s ", ShortNameOf (DefinitionOf (Type))); fprintf (File, "%s ", (FeatureDefs.FeatureDesc[Type])->ShortName);
WriteFeatureSet (File, FeaturesOfType (CharDesc, Type)); WriteFeatureSet (File, CharDesc->FeatureSets[Type]);
} }
} /* WriteCharDescription */ } /* WriteCharDescription */
@ -205,15 +205,15 @@ CHAR_DESC ReadCharDescription(FILE *File) {
int Type; int Type;
if (fscanf (File, "%d", &NumSetsToRead) != 1 || if (fscanf (File, "%d", &NumSetsToRead) != 1 ||
NumSetsToRead < 0 || NumSetsToRead > NumFeaturesDefined ()) NumSetsToRead < 0 || NumSetsToRead > FeatureDefs.NumFeatureTypes)
DoError (ILLEGAL_NUM_SETS, "Illegal number of feature sets"); DoError (ILLEGAL_NUM_SETS, "Illegal number of feature sets");
CharDesc = NewCharDescription (); CharDesc = NewCharDescription ();
for (; NumSetsToRead > 0; NumSetsToRead--) { for (; NumSetsToRead > 0; NumSetsToRead--) {
fscanf (File, "%s", ShortName); fscanf (File, "%s", ShortName);
Type = ShortNameToFeatureType (ShortName); Type = ShortNameToFeatureType (ShortName);
FeaturesOfType (CharDesc, Type) = CharDesc->FeatureSets[Type] =
ReadFeatureSet (File, DefinitionOf (Type)); ReadFeatureSet (File, FeatureDefs.FeatureDesc[Type]);
} }
return (CharDesc); return (CharDesc);
@ -235,8 +235,8 @@ int ShortNameToFeatureType(const char *ShortName) {
*/ */
int i; int i;
for (i = 0; i < NumFeaturesDefined (); i++) for (i = 0; i < FeatureDefs.NumFeatureTypes; i++)
if (!strcmp (ShortNameOf (DefinitionOf (i)), ShortName)) if (!strcmp ((FeatureDefs.FeatureDesc[i]->ShortName), ShortName))
return (i); return (i);
DoError (ILLEGAL_SHORT_NAME, "Illegal short name for a feature"); DoError (ILLEGAL_SHORT_NAME, "Illegal short name for a feature");
return 0; return 0;

View File

@ -51,20 +51,6 @@ typedef struct
} FEATURE_DEFS_STRUCT; } FEATURE_DEFS_STRUCT;
typedef FEATURE_DEFS_STRUCT *FEATURE_DEFS; typedef FEATURE_DEFS_STRUCT *FEATURE_DEFS;
/*----------------------------------------------------------------------
Macros for finding feature definitions
----------------------------------------------------------------------*/
#define NumFeaturesDefined() (FeatureDefs.NumFeatureTypes)
#define DefinitionOf(Type) (FeatureDefs.FeatureDesc[Type])
#define ExtractorOf(Type) (FeatureDefs.FeatureExtractors[Type])
#define FeatureOn(Type) (FeatureDefs.FeatureEnabled[Type])
/*----------------------------------------------------------------------
Macros for manipulating character descriptions
----------------------------------------------------------------------*/
#define NumFeatureSetsIn(Char) ((Char)->NumFeatureSets)
#define FeaturesOfType(Char, Type) ((Char)->FeatureSets[Type])
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
Generic functions for manipulating character descriptions Generic functions for manipulating character descriptions
----------------------------------------------------------------------*/ ----------------------------------------------------------------------*/

View File

@ -47,10 +47,11 @@ CHAR_DESC ExtractFlexFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
CharDesc = NewCharDescription (); CharDesc = NewCharDescription ();
for (Type = 0; Type < NumFeatureSetsIn(CharDesc); Type++) for (Type = 0; Type < CharDesc->NumFeatureSets; Type++)
if (ExtractorOf(Type) != NULL && ExtractorOf(Type)->Extractor != NULL) if (FeatureDefs.FeatureExtractors[Type] != NULL &&
FeaturesOfType(CharDesc, Type) = FeatureDefs.FeatureExtractors[Type]->Extractor != NULL)
ExtractUsing(ExtractorOf(Type)) (Blob, LineStats); CharDesc->FeatureSets[Type] =
(FeatureDefs.FeatureExtractors[Type])->Extractor (Blob, LineStats);
return (CharDesc); return (CharDesc);
@ -80,7 +81,7 @@ InitFlexFXVars ()
int Type; int Type;
SetupExtractors(); SetupExtractors();
for (Type = 0; Type < NumFeaturesDefined (); Type++) { for (Type = 0; Type < FeatureDefs.NumFeatureTypes; Type++) {
InitFXVarsUsing (ExtractorOf (Type)) (); (FeatureDefs.FeatureExtractors[Type])->InitExtractorVars ();
} }
} /* InitFlexFXVars */ } /* InitFlexFXVars */

View File

@ -45,7 +45,7 @@ void ClearCharNormArray(INT_TEMPLATES Templates,
*/ */
int i; int i;
for (i = 0; i < NumClassesIn (Templates); i++) { for (i = 0; i < Templates->NumClasses; i++) {
CharNormArray[i] = 0; CharNormArray[i] = 0;
} }
@ -74,9 +74,9 @@ void ComputeIntCharNormArray(FEATURE NormFeature,
int i; int i;
int NormAdjust; int NormAdjust;
for (i = 0; i < NumClassesIn (Templates); i++) { for (i = 0; i < Templates->NumClasses; i++) {
NormAdjust = (int) (INT_CHAR_NORM_RANGE * NormAdjust = (int) (INT_CHAR_NORM_RANGE *
ComputeNormMatch (ClassIdForIndex (Templates, i), ComputeNormMatch (Templates->ClassIdFor[i],
NormFeature, FALSE)); NormFeature, FALSE));
if (NormAdjust < 0) if (NormAdjust < 0)
NormAdjust = 0; NormAdjust = 0;
@ -112,14 +112,14 @@ void ComputeIntFeatures(FEATURE_SET Features, INT_FEATURE_ARRAY IntFeatures) {
else else
YShift = Y_SHIFT; YShift = Y_SHIFT;
for (Fid = 0; Fid < NumFeaturesIn (Features); Fid++) { for (Fid = 0; Fid < Features->NumFeatures; Fid++) {
Feature = FeatureIn (Features, Fid); Feature = Features->Features[Fid];
IntFeatures[Fid].X = BucketFor (ParamOf (Feature, PicoFeatX), IntFeatures[Fid].X = BucketFor (Feature->Params[PicoFeatX],
X_SHIFT, INT_FEAT_RANGE); X_SHIFT, INT_FEAT_RANGE);
IntFeatures[Fid].Y = BucketFor (ParamOf (Feature, PicoFeatY), IntFeatures[Fid].Y = BucketFor (Feature->Params[PicoFeatY],
YShift, INT_FEAT_RANGE); YShift, INT_FEAT_RANGE);
IntFeatures[Fid].Theta = CircBucketFor (ParamOf (Feature, PicoFeatDir), IntFeatures[Fid].Theta = CircBucketFor (Feature->Params[PicoFeatDir],
ANGLE_SHIFT, INT_FEAT_RANGE); ANGLE_SHIFT, INT_FEAT_RANGE);
IntFeatures[Fid].CP_misses = 0; IntFeatures[Fid].CP_misses = 0;
} }

View File

@ -27,6 +27,23 @@
Public Code Public Code
----------------------------------------------------------------------------**/ ----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void FillPoint(FPOINT &P, FLOAT32 X, FLOAT32 Y) {
P.x = X;
P.y = Y;
}
/* Commented out, because there is also a same function for TPOINT and this gets resolved to it.
void CopyPoint(FPOINT &A, FPOINT &B) {
B.x = A.x;
B.y = A.y;
}
*/
FLOAT32 DistanceBetween(FPOINT A, FPOINT B) {
return sqrt ((double) (XDelta(A,B) * XDelta(A,B) + YDelta(A,B) * YDelta(A,B)));
}
FLOAT32 NormalizedAngleFrom(FPOINT *Point1, FLOAT32 NormalizedAngleFrom(FPOINT *Point1,
FPOINT *Point2, FPOINT *Point2,
FLOAT32 FullScale) { FLOAT32 FullScale) {

View File

@ -36,27 +36,28 @@ typedef FPOINT FVECTOR;
Macros Macros
----------------------------------------------------------------------------**/ ----------------------------------------------------------------------------**/
/* macros for manipulating simple point data structures */ /* macros for manipulating simple point data structures */
#define Xof(P) ( (P).x ) //#define Xof(P) ( (P).x )
#define Yof(P) ( (P).y ) //#define Yof(P) ( (P).y )
#define XofP(P) ((P)->x) //#define YofP(P) ((P)->y)
#define YofP(P) ((P)->y) //#define XofP(P) ((P)->x)
#define FillPoint(P,X,Y) ( Xof(P) = (X), Yof(P) = (Y) )
#define CopyPoint(A,B) ( Xof(B) = Xof(A), Yof(B) = Yof(A) )
/* macros for computing miscellaneous functions of 2 points */ /* macros for computing miscellaneous functions of 2 points */
#define XDelta(A,B) ( Xof(B) - Xof(A) ) #define XDelta(A,B) ( (B).x - (A).x )
#define YDelta(A,B) ( Yof(B) - Yof(A) ) #define YDelta(A,B) ( (B).y - (A).y )
#define DistanceBetween(A,B) \ #define CopyPoint(A, B) ((B).x = (A).x, (B).y = (A).y) // FIXME, gets expanded for FPOINT and TPOINT.
(sqrt ((double) (XDelta(A,B) * XDelta(A,B) + YDelta(A,B) * YDelta(A,B))))
#define SlopeFrom(A,B) ( YDelta(A,B) / XDelta(A,B) ) #define SlopeFrom(A,B) ( YDelta(A,B) / XDelta(A,B) )
#define AngleFrom(A,B) ( atan2((double) YDelta(A,B), \ #define AngleFrom(A,B) ( atan2((double) YDelta(A,B), \
(double) XDelta(A,B) ) ) (double) XDelta(A,B) ) )
#define XIntersectionOf(A,B,X) ( SlopeFrom(A,B) * ((X) - Xof(A)) + Yof(A)) #define XIntersectionOf(A,B,X) ( SlopeFrom(A,B) * ((X) - A.x) + A.y)
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
Public Function Prototypes Public Function Prototypes
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
void FillPoint(FPOINT &P, FLOAT32 X, FLOAT32 Y);
FLOAT32 DistanceBetween(FPOINT A, FPOINT B);
FLOAT32 NormalizedAngleFrom(FPOINT *Point1, FPOINT *Point2, FLOAT32 FullScale); FLOAT32 NormalizedAngleFrom(FPOINT *Point1, FPOINT *Point2, FLOAT32 FullScale);
#endif #endif

View File

@ -48,7 +48,7 @@ FEATURE_EXT_STRUCT* ExtractorDefs[NUM_FEATURE_TYPES] = {
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void SetupExtractors() { void SetupExtractors() {
for (int i = 0; i < NUM_FEATURE_TYPES; ++i) for (int i = 0; i < NUM_FEATURE_TYPES; ++i)
ExtractorOf(i) = ExtractorDefs[i]; FeatureDefs.FeatureExtractors[i] = ExtractorDefs[i];
} }
void GetLineStatsFromRow(TEXTROW *Row, LINE_STATS *LineStats) { void GetLineStatsFromRow(TEXTROW *Row, LINE_STATS *LineStats) {

View File

@ -50,7 +50,7 @@
**********************************************************************/ **********************************************************************/
#define is_hidden_edge(edge) \ #define is_hidden_edge(edge) \
/*(hidden_edges &&*/ edge->flags[0] /*) */ /*(hidden_edges &&*/ (edge->flags[0]) /*) */
/********************************************************************** /**********************************************************************
* hide_edge * hide_edge

View File

@ -210,7 +210,7 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
int *ClassCountPtr; int *ClassCountPtr;
CLASS_ID classch; CLASS_ID classch;
MaxNumClasses = NumClassesIn (IntTemplates); MaxNumClasses = IntTemplates->NumClasses;
/* Clear Class Counts */ /* Clear Class Counts */
ClassCountPtr = &(ClassCount[0]); ClassCountPtr = &(ClassCount[0]);
@ -219,7 +219,7 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
} }
/* Update Class Counts */ /* Update Class Counts */
NumPruners = NumClassPrunersIn (IntTemplates); NumPruners = IntTemplates->NumClassPruners;
for (feature_index = 0; feature_index < NumFeatures; feature_index++) { for (feature_index = 0; feature_index < NumFeatures; feature_index++) {
feature = &Features[feature_index]; feature = &Features[feature_index];
feature_address = (((feature->X * NUM_CP_BUCKETS >> 8) * NUM_CP_BUCKETS feature_address = (((feature->X * NUM_CP_BUCKETS >> 8) * NUM_CP_BUCKETS
@ -227,7 +227,7 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
(feature->Y * NUM_CP_BUCKETS >> 8)) * (feature->Y * NUM_CP_BUCKETS >> 8)) *
NUM_CP_BUCKETS + NUM_CP_BUCKETS +
(feature->Theta * NUM_CP_BUCKETS >> 8)) << 1; (feature->Theta * NUM_CP_BUCKETS >> 8)) << 1;
ClassPruner = ClassPrunersFor (IntTemplates); ClassPruner = IntTemplates->ClassPruner;
class_index = 0; class_index = 0;
for (PrunerSet = 0; PrunerSet < NumPruners; PrunerSet++, ClassPruner++) { for (PrunerSet = 0; PrunerSet < NumPruners; PrunerSet++, ClassPruner++) {
BasePrunerAddress = (uinT32 *) (*ClassPruner) + feature_address; BasePrunerAddress = (uinT32 *) (*ClassPruner) + feature_address;
@ -276,7 +276,7 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
ClassCount[Class] -= ClassCount[Class] * deficit / ClassCount[Class] -= ClassCount[Class] * deficit /
(NumFeatures*CPCutoffStrength + deficit); (NumFeatures*CPCutoffStrength + deficit);
} }
if (!unicharset.get_enabled(ClassIdForIndex(IntTemplates, Class))) if (!unicharset.get_enabled(IntTemplates->ClassIdFor[Class]))
ClassCount[Class] = 0; // This char is disabled! ClassCount[Class] = 0; // This char is disabled!
} }
@ -311,7 +311,7 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
if (display_ratings > 1) { if (display_ratings > 1) {
cprintf ("CP:%d classes, %d features:\n", NumClasses, NumFeatures); cprintf ("CP:%d classes, %d features:\n", NumClasses, NumFeatures);
for (Class = 0; Class < NumClasses; Class++) { for (Class = 0; Class < NumClasses; Class++) {
classch = ClassIdForIndex (IntTemplates, SortIndex[NumClasses - Class]); classch = IntTemplates->ClassIdFor[SortIndex[NumClasses - Class]];
cprintf ("%s:C=%d, E=%d, N=%d, Rat=%d\n", cprintf ("%s:C=%d, E=%d, N=%d, Rat=%d\n",
unicharset.id_to_unichar(classch), unicharset.id_to_unichar(classch),
ClassCount[SortIndex[NumClasses - Class]], ClassCount[SortIndex[NumClasses - Class]],
@ -321,7 +321,7 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
(cp_maps[3] * NumFeatures)); (cp_maps[3] * NumFeatures));
} }
if (display_ratings > 2) { if (display_ratings > 2) {
NumPruners = NumClassPrunersIn (IntTemplates); NumPruners = IntTemplates->NumClassPruners;
for (feature_index = 0; feature_index < NumFeatures; for (feature_index = 0; feature_index < NumFeatures;
feature_index++) { feature_index++) {
cprintf ("F=%3d,", feature_index); cprintf ("F=%3d,", feature_index);
@ -330,7 +330,7 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
(((feature->X * NUM_CP_BUCKETS >> 8) * NUM_CP_BUCKETS + (((feature->X * NUM_CP_BUCKETS >> 8) * NUM_CP_BUCKETS +
(feature->Y * NUM_CP_BUCKETS >> 8)) * NUM_CP_BUCKETS + (feature->Y * NUM_CP_BUCKETS >> 8)) * NUM_CP_BUCKETS +
(feature->Theta * NUM_CP_BUCKETS >> 8)) << 1; (feature->Theta * NUM_CP_BUCKETS >> 8)) << 1;
ClassPruner = ClassPrunersFor (IntTemplates); ClassPruner = IntTemplates->ClassPruner;
class_index = 0; class_index = 0;
for (PrunerSet = 0; PrunerSet < NumPruners; for (PrunerSet = 0; PrunerSet < NumPruners;
PrunerSet++, ClassPruner++) { PrunerSet++, ClassPruner++) {
@ -342,8 +342,7 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
for (Class = 0; Class < 16; Class++, class_index++) { for (Class = 0; Class < 16; Class++, class_index++) {
if (NormCount[class_index] >= MaxCount) if (NormCount[class_index] >= MaxCount)
cprintf (" %s=%d,", cprintf (" %s=%d,",
unicharset.id_to_unichar(ClassIdForIndex (IntTemplates, unicharset.id_to_unichar(IntTemplates->ClassIdFor[class_index]),
class_index)),
PrunerWord & 3); PrunerWord & 3);
PrunerWord >>= 2; PrunerWord >>= 2;
} }
@ -355,7 +354,7 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
for (Class = 0; Class < MaxNumClasses; Class++) { for (Class = 0; Class < MaxNumClasses; Class++) {
if (NormCount[Class] > MaxCount) if (NormCount[Class] > MaxCount)
cprintf (" %s=%d,", cprintf (" %s=%d,",
unicharset.id_to_unichar(ClassIdForIndex (IntTemplates, Class)), unicharset.id_to_unichar(IntTemplates->ClassIdFor[Class]),
-((ClassPrunerMultiplier * -((ClassPrunerMultiplier *
NormalizationFactors[Class]) >> 8) * cp_maps[3] / NormalizationFactors[Class]) >> 8) * cp_maps[3] /
3); 3);
@ -368,7 +367,7 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
max_rating = 0.0f; max_rating = 0.0f;
for (Class = 0, out_class = 0; Class < NumClasses; Class++) { for (Class = 0, out_class = 0; Class < NumClasses; Class++) {
Results[out_class].Class = Results[out_class].Class =
ClassIdForIndex (IntTemplates, SortIndex[NumClasses - Class]); IntTemplates->ClassIdFor[SortIndex[NumClasses - Class]];
Results[out_class].Rating = Results[out_class].Rating =
1.0 - SortKey[NumClasses - 1.0 - SortKey[NumClasses -
Class] / ((float) cp_maps[3] * NumFeatures); Class] / ((float) cp_maps[3] * NumFeatures);
@ -559,17 +558,17 @@ int FindGoodProtos(INT_CLASS ClassTemplate,
#endif #endif
/* Average Proto Evidences & Find Good Protos */ /* Average Proto Evidences & Find Good Protos */
NumProtos = NumIntProtosIn (ClassTemplate); NumProtos = ClassTemplate->NumProtos;
NumGoodProtos = 0; NumGoodProtos = 0;
for (ActualProtoNum = 0; ActualProtoNum < NumProtos; ActualProtoNum++) { for (ActualProtoNum = 0; ActualProtoNum < NumProtos; ActualProtoNum++) {
/* Compute Average for Actual Proto */ /* Compute Average for Actual Proto */
Temp = 0; Temp = 0;
UINT8Pointer = &(ProtoEvidence[ActualProtoNum][0]); UINT8Pointer = &(ProtoEvidence[ActualProtoNum][0]);
for (ProtoIndex = LengthForProtoId (ClassTemplate, ActualProtoNum); for (ProtoIndex = ClassTemplate->ProtoLengths[ActualProtoNum];
ProtoIndex > 0; ProtoIndex--, UINT8Pointer++) ProtoIndex > 0; ProtoIndex--, UINT8Pointer++)
Temp += *UINT8Pointer; Temp += *UINT8Pointer;
Temp /= LengthForProtoId (ClassTemplate, ActualProtoNum); Temp /= ClassTemplate->ProtoLengths[ActualProtoNum];
/* Find Good Protos */ /* Find Good Protos */
if (Temp >= AdaptProtoThresh) { if (Temp >= AdaptProtoThresh) {
@ -637,7 +636,7 @@ int FindBadFeatures(INT_CLASS ClassTemplate,
IMClearTables(ClassTemplate, SumOfFeatureEvidence, ProtoEvidence); IMClearTables(ClassTemplate, SumOfFeatureEvidence, ProtoEvidence);
NumBadFeatures = 0; NumBadFeatures = 0;
NumConfigs = NumIntConfigsIn (ClassTemplate); NumConfigs = ClassTemplate->NumConfigs;
for (Feature = 0; Feature < NumFeatures; Feature++) { for (Feature = 0; Feature < NumFeatures; Feature++) {
IMUpdateTablesForFeature (ClassTemplate, ProtoMask, ConfigMask, Feature, IMUpdateTablesForFeature (ClassTemplate, ProtoMask, ConfigMask, Feature,
&(Features[Feature]), FeatureEvidence, &(Features[Feature]), FeatureEvidence,
@ -797,8 +796,8 @@ uinT8 ProtoEvidence[MAX_NUM_PROTOS][MAX_PROTO_INDEX]) {
** Exceptions: none ** Exceptions: none
** History: Wed Feb 27 14:12:28 MST 1991, RWM, Created. ** History: Wed Feb 27 14:12:28 MST 1991, RWM, Created.
*/ */
int NumProtos = NumIntProtosIn (ClassTemplate); int NumProtos = ClassTemplate->NumProtos;
int NumConfigs = NumIntConfigsIn (ClassTemplate); int NumConfigs = ClassTemplate->NumConfigs;
memset(SumOfFeatureEvidence, 0, memset(SumOfFeatureEvidence, 0,
NumConfigs * sizeof(SumOfFeatureEvidence[0])); NumConfigs * sizeof(SumOfFeatureEvidence[0]));
@ -935,8 +934,7 @@ int Debug) {
register inT32 A3; register inT32 A3;
register uinT32 A4; register uinT32 A4;
IMClearFeatureEvidenceTable (FeatureEvidence, IMClearFeatureEvidenceTable(FeatureEvidence, ClassTemplate->NumConfigs);
NumIntConfigsIn (ClassTemplate));
/* Precompute Feature Address offset for Proto Pruning */ /* Precompute Feature Address offset for Proto Pruning */
XFeatureAddress = ((Feature->X >> 2) << 1); XFeatureAddress = ((Feature->X >> 2) << 1);
@ -944,8 +942,8 @@ int Debug) {
ThetaFeatureAddress = (NUM_PP_BUCKETS << 2) + ((Feature->Theta >> 2) << 1); ThetaFeatureAddress = (NUM_PP_BUCKETS << 2) + ((Feature->Theta >> 2) << 1);
for (ProtoSetIndex = 0, ActualProtoNum = 0; for (ProtoSetIndex = 0, ActualProtoNum = 0;
ProtoSetIndex < NumProtoSetsIn (ClassTemplate); ProtoSetIndex++) { ProtoSetIndex < ClassTemplate->NumProtoSets; ProtoSetIndex++) {
ProtoSet = ProtoSetIn (ClassTemplate, ProtoSetIndex); ProtoSet = ClassTemplate->ProtoSets[ProtoSetIndex];
ProtoPrunerPtr = (uinT32 *) ((*ProtoSet).ProtoPruner); ProtoPrunerPtr = (uinT32 *) ((*ProtoSet).ProtoPruner);
for (ProtoNum = 0; ProtoNum < PROTOS_PER_PROTO_SET; for (ProtoNum = 0; ProtoNum < PROTOS_PER_PROTO_SET;
ProtoNum += (PROTOS_PER_PROTO_SET >> 1), ActualProtoNum += ProtoNum += (PROTOS_PER_PROTO_SET >> 1), ActualProtoNum +=
@ -1019,8 +1017,7 @@ int Debug) {
UINT8Pointer = UINT8Pointer =
&(ProtoEvidence[ActualProtoNum + proto_offset][0]); &(ProtoEvidence[ActualProtoNum + proto_offset][0]);
for (ProtoIndex = for (ProtoIndex =
LengthForProtoId (ClassTemplate, ClassTemplate->ProtoLengths[ActualProtoNum + proto_offset];
ActualProtoNum + proto_offset);
ProtoIndex > 0; ProtoIndex--, UINT8Pointer++) { ProtoIndex > 0; ProtoIndex--, UINT8Pointer++) {
if (Evidence > *UINT8Pointer) { if (Evidence > *UINT8Pointer) {
Temp = *UINT8Pointer; Temp = *UINT8Pointer;
@ -1037,12 +1034,11 @@ int Debug) {
if (PrintFeatureMatchesOn (Debug)) if (PrintFeatureMatchesOn (Debug))
IMDebugConfigurationSum (FeatureNum, FeatureEvidence, IMDebugConfigurationSum (FeatureNum, FeatureEvidence,
NumIntConfigsIn (ClassTemplate)); ClassTemplate->NumConfigs);
IntPointer = SumOfFeatureEvidence; IntPointer = SumOfFeatureEvidence;
UINT8Pointer = FeatureEvidence; UINT8Pointer = FeatureEvidence;
int SumOverConfigs = 0; int SumOverConfigs = 0;
for (ConfigNum = NumIntConfigsIn (ClassTemplate); ConfigNum > 0; for (ConfigNum = ClassTemplate->NumConfigs; ConfigNum > 0; ConfigNum--) {
ConfigNum--) {
int evidence = *UINT8Pointer++; int evidence = *UINT8Pointer++;
SumOverConfigs += evidence; SumOverConfigs += evidence;
*IntPointer++ += evidence; *IntPointer++ += evidence;
@ -1085,8 +1081,8 @@ inT16 NumFeatures, int Debug) {
int Temp; int Temp;
int NumConfigs; int NumConfigs;
NumProtos = NumIntProtosIn (ClassTemplate); NumProtos = ClassTemplate->NumProtos;
NumConfigs = NumIntConfigsIn (ClassTemplate); NumConfigs = ClassTemplate->NumConfigs;
if (PrintMatchSummaryOn (Debug)) { if (PrintMatchSummaryOn (Debug)) {
cprintf ("Configuration Mask:\n"); cprintf ("Configuration Mask:\n");
@ -1105,7 +1101,7 @@ inT16 NumFeatures, int Debug) {
if (PrintMatchSummaryOn (Debug)) { if (PrintMatchSummaryOn (Debug)) {
cprintf ("Proto Mask:\n"); cprintf ("Proto Mask:\n");
for (ProtoSetIndex = 0; ProtoSetIndex < NumProtoSetsIn (ClassTemplate); for (ProtoSetIndex = 0; ProtoSetIndex < ClassTemplate->NumProtoSets;
ProtoSetIndex++) { ProtoSetIndex++) {
ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET); ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET);
for (ProtoWordNum = 0; ProtoWordNum < 2; for (ProtoWordNum = 0; ProtoWordNum < 2;
@ -1127,9 +1123,9 @@ inT16 NumFeatures, int Debug) {
if (PrintProtoMatchesOn (Debug)) { if (PrintProtoMatchesOn (Debug)) {
cprintf ("Proto Evidence:\n"); cprintf ("Proto Evidence:\n");
for (ProtoSetIndex = 0; ProtoSetIndex < NumProtoSetsIn (ClassTemplate); for (ProtoSetIndex = 0; ProtoSetIndex < ClassTemplate->NumProtoSets;
ProtoSetIndex++) { ProtoSetIndex++) {
ProtoSet = ProtoSetIn (ClassTemplate, ProtoSetIndex); ProtoSet = ClassTemplate->ProtoSets[ProtoSetIndex];
ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET); ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET);
for (ProtoNum = 0; for (ProtoNum = 0;
((ProtoNum < PROTOS_PER_PROTO_SET) ((ProtoNum < PROTOS_PER_PROTO_SET)
@ -1139,16 +1135,14 @@ inT16 NumFeatures, int Debug) {
Temp = 0; Temp = 0;
UINT8Pointer = &(ProtoEvidence[ActualProtoNum][0]); UINT8Pointer = &(ProtoEvidence[ActualProtoNum][0]);
for (ProtoIndex = 0; for (ProtoIndex = 0;
ProtoIndex < LengthForProtoId (ClassTemplate, ProtoIndex < ClassTemplate->ProtoLengths[ActualProtoNum];
ActualProtoNum);
ProtoIndex++, UINT8Pointer++) { ProtoIndex++, UINT8Pointer++) {
cprintf (" %d", *UINT8Pointer); cprintf (" %d", *UINT8Pointer);
Temp += *UINT8Pointer; Temp += *UINT8Pointer;
} }
cprintf (" = %6.4f%%\n", Temp / cprintf (" = %6.4f%%\n", Temp /
256.0 / LengthForProtoId (ClassTemplate, 256.0 / ClassTemplate->ProtoLengths[ActualProtoNum]);
ActualProtoNum));
ConfigWord = (ProtoSet->Protos[ProtoNum]).Configs[0]; ConfigWord = (ProtoSet->Protos[ProtoNum]).Configs[0];
IntPointer = SumOfFeatureEvidence; IntPointer = SumOfFeatureEvidence;
@ -1172,8 +1166,7 @@ inT16 NumFeatures, int Debug) {
cprintf (" %5.1f", cprintf (" %5.1f",
100.0 * (1.0 - 100.0 * (1.0 -
ProtoConfigs[ConfigNum] / ProtoConfigs[ConfigNum] /
LengthForConfigId (ClassTemplate, ClassTemplate->ConfigLengths[ConfigNum] / 256.0));
ConfigNum) / 256.0));
cprintf ("\n\n"); cprintf ("\n\n");
} }
@ -1186,7 +1179,7 @@ inT16 NumFeatures, int Debug) {
cprintf ("Proto Length for Configurations:\n"); cprintf ("Proto Length for Configurations:\n");
for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++) for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++)
cprintf (" %4.1f", cprintf (" %4.1f",
(float) LengthForConfigId (ClassTemplate, ConfigNum)); (float) ClassTemplate->ConfigLengths[ConfigNum]);
cprintf ("\n\n"); cprintf ("\n\n");
} }
@ -1217,11 +1210,11 @@ int Debug) {
520, 520, 520, 520,
-130.0, 130.0, -130.0, 130.0); -130.0, 130.0, -130.0, 130.0);
} }
NumProtos = NumIntProtosIn (ClassTemplate); NumProtos = ClassTemplate->NumProtos;
for (ProtoSetIndex = 0; ProtoSetIndex < NumProtoSetsIn (ClassTemplate); for (ProtoSetIndex = 0; ProtoSetIndex < ClassTemplate->NumProtoSets;
ProtoSetIndex++) { ProtoSetIndex++) {
ProtoSet = ProtoSetIn (ClassTemplate, ProtoSetIndex); ProtoSet = ClassTemplate->ProtoSets[ProtoSetIndex];
ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET); ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET);
for (ProtoNum = 0; for (ProtoNum = 0;
((ProtoNum < PROTOS_PER_PROTO_SET) ((ProtoNum < PROTOS_PER_PROTO_SET)
@ -1229,11 +1222,11 @@ int Debug) {
/* Compute Average for Actual Proto */ /* Compute Average for Actual Proto */
Temp = 0; Temp = 0;
UINT8Pointer = &(ProtoEvidence[ActualProtoNum][0]); UINT8Pointer = &(ProtoEvidence[ActualProtoNum][0]);
for (ProtoIndex = LengthForProtoId (ClassTemplate, ActualProtoNum); for (ProtoIndex = ClassTemplate->ProtoLengths[ActualProtoNum];
ProtoIndex > 0; ProtoIndex--, UINT8Pointer++) ProtoIndex > 0; ProtoIndex--, UINT8Pointer++)
Temp += *UINT8Pointer; Temp += *UINT8Pointer;
Temp /= LengthForProtoId (ClassTemplate, ActualProtoNum); Temp /= ClassTemplate->ProtoLengths[ActualProtoNum];
ConfigWord = (ProtoSet->Protos[ProtoNum]).Configs[0]; ConfigWord = (ProtoSet->Protos[ProtoNum]).Configs[0];
ConfigWord &= *ConfigMask; ConfigWord &= *ConfigMask;
@ -1275,7 +1268,7 @@ void IMDisplayFeatureDebugInfo(INT_CLASS ClassTemplate,
IMClearTables(ClassTemplate, SumOfFeatureEvidence, ProtoEvidence); IMClearTables(ClassTemplate, SumOfFeatureEvidence, ProtoEvidence);
NumConfigs = NumIntConfigsIn (ClassTemplate); NumConfigs = ClassTemplate->NumConfigs;
for (Feature = 0; Feature < NumFeatures; Feature++) { for (Feature = 0; Feature < NumFeatures; Feature++) {
IMUpdateTablesForFeature (ClassTemplate, ProtoMask, ConfigMask, Feature, IMUpdateTablesForFeature (ClassTemplate, ProtoMask, ConfigMask, Feature,
&(Features[Feature]), FeatureEvidence, &(Features[Feature]), FeatureEvidence,
@ -1330,18 +1323,18 @@ inT16 NumFeatures) {
uinT16 ActualProtoNum; uinT16 ActualProtoNum;
int Temp; int Temp;
NumProtos = NumIntProtosIn (ClassTemplate); NumProtos = ClassTemplate->NumProtos;
for (ProtoSetIndex = 0; ProtoSetIndex < NumProtoSetsIn (ClassTemplate); for (ProtoSetIndex = 0; ProtoSetIndex < ClassTemplate->NumProtoSets;
ProtoSetIndex++) { ProtoSetIndex++) {
ProtoSet = ProtoSetIn (ClassTemplate, ProtoSetIndex); ProtoSet = ClassTemplate->ProtoSets[ProtoSetIndex];
ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET); ActualProtoNum = (ProtoSetIndex * PROTOS_PER_PROTO_SET);
for (ProtoNum = 0; for (ProtoNum = 0;
((ProtoNum < PROTOS_PER_PROTO_SET) ((ProtoNum < PROTOS_PER_PROTO_SET)
&& (ActualProtoNum < NumProtos)); ProtoNum++, ActualProtoNum++) { && (ActualProtoNum < NumProtos)); ProtoNum++, ActualProtoNum++) {
Temp = 0; Temp = 0;
UINT8Pointer = &(ProtoEvidence[ActualProtoNum][0]); UINT8Pointer = &(ProtoEvidence[ActualProtoNum][0]);
for (ProtoIndex = LengthForProtoId (ClassTemplate, ActualProtoNum); for (ProtoIndex = ClassTemplate->ProtoLengths[ActualProtoNum];
ProtoIndex > 0; ProtoIndex--, UINT8Pointer++) ProtoIndex > 0; ProtoIndex--, UINT8Pointer++)
Temp += *UINT8Pointer; Temp += *UINT8Pointer;
@ -1380,12 +1373,12 @@ inT16 NumFeatures, inT32 used_features) {
register int ConfigNum; register int ConfigNum;
int NumConfigs; int NumConfigs;
NumConfigs = NumIntConfigsIn (ClassTemplate); NumConfigs = ClassTemplate->NumConfigs;
IntPointer = SumOfFeatureEvidence; IntPointer = SumOfFeatureEvidence;
for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++, IntPointer++) for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++, IntPointer++)
*IntPointer = (*IntPointer << 8) / *IntPointer = (*IntPointer << 8) /
(NumFeatures + LengthForConfigId (ClassTemplate, ConfigNum)); (NumFeatures + ClassTemplate->ConfigLengths[ConfigNum]);
} }
@ -1412,7 +1405,7 @@ uinT8 NormalizationFactor, INT_RESULT Result) {
register int BestMatch; register int BestMatch;
register int Best2Match; register int Best2Match;
NumConfigs = NumIntConfigsIn (ClassTemplate); NumConfigs = ClassTemplate->NumConfigs;
/* Find best match */ /* Find best match */
BestMatch = 0; BestMatch = 0;

View File

@ -292,16 +292,16 @@ int AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class) {
assert (LegalClassId (ClassId)); assert (LegalClassId (ClassId));
assert (UnusedClassIdIn (Templates, ClassId)); assert (UnusedClassIdIn (Templates, ClassId));
Index = NumClassesIn (Templates); Index = Templates->NumClasses;
IndexForClassId (Templates, ClassId) = Index; Templates->IndexFor[ClassId] = Index;
ClassIdForIndex (Templates, Index) = ClassId; Templates->ClassIdFor[Index] = ClassId;
NumClassesIn (Templates)++; Templates->NumClasses++;
ClassForIndex (Templates, Index) = Class; Templates->Class[Index] = Class;
if (NumClassesIn (Templates) > MaxNumClassesIn (Templates)) { if (Templates->NumClasses > MaxNumClassesIn (Templates)) {
Pruner = NumClassPrunersIn (Templates); Pruner = Templates->NumClassPruners;
NumClassPrunersIn (Templates)++; Templates->NumClassPruners++;
Templates->ClassPruner[Pruner] = Templates->ClassPruner[Pruner] =
(CLASS_PRUNER) Emalloc (sizeof (CLASS_PRUNER_STRUCT)); (CLASS_PRUNER) Emalloc (sizeof (CLASS_PRUNER_STRUCT));
@ -329,11 +329,11 @@ int AddIntConfig(INT_CLASS Class) {
*/ */
int Index; int Index;
assert (NumIntConfigsIn (Class) < MAX_NUM_CONFIGS); assert (Class->NumConfigs < MAX_NUM_CONFIGS);
Index = NumIntConfigsIn (Class); Index = Class->NumConfigs;
NumIntConfigsIn (Class)++; Class->NumConfigs++;
LengthForConfigId (Class, Index) = 0; Class->ConfigLengths[Index] = 0;
return (Index); return (Index);
} /* AddIntConfig */ } /* AddIntConfig */
@ -356,20 +356,18 @@ int AddIntProto(INT_CLASS Class) {
INT_PROTO Proto; INT_PROTO Proto;
register uinT32 *Word; register uinT32 *Word;
if (NumIntProtosIn (Class) >= MAX_NUM_PROTOS) if (Class->NumProtos >= MAX_NUM_PROTOS)
return (NO_PROTO); return (NO_PROTO);
Index = NumIntProtosIn (Class); Index = Class->NumProtos++;
NumIntProtosIn (Class)++;
if (NumIntProtosIn (Class) > MaxNumIntProtosIn (Class)) { if (Class->NumProtos > MaxNumIntProtosIn(Class)) {
ProtoSetId = NumProtoSetsIn (Class); ProtoSetId = Class->NumProtoSets++;
NumProtoSetsIn (Class)++;
ProtoSet = (PROTO_SET) Emalloc (sizeof (PROTO_SET_STRUCT)); ProtoSet = (PROTO_SET) Emalloc (sizeof (PROTO_SET_STRUCT));
ProtoSetIn (Class, ProtoSetId) = ProtoSet; Class->ProtoSets[ProtoSetId] = ProtoSet;
for (Word = (uinT32 *) (ProtoPrunerFor (ProtoSet)); for (Word = (uinT32 *) (ProtoSet->ProtoPruner);
Word < (uinT32 *) (ProtoPrunerFor (ProtoSet)) + WERDS_PER_PP; Word < (uinT32 *) (ProtoSet->ProtoPruner) + WERDS_PER_PP;
*Word++ = 0); *Word++ = 0);
/* reallocate space for the proto lengths and install in class */ /* reallocate space for the proto lengths and install in class */
@ -379,7 +377,7 @@ int AddIntProto(INT_CLASS Class) {
} }
/* initialize proto so its length is zero and it isn't in any configs */ /* initialize proto so its length is zero and it isn't in any configs */
LengthForProtoId (Class, Index) = 0; Class->ProtoLengths[Index] = 0;
Proto = ProtoForProtoId (Class, Index); Proto = ProtoForProtoId (Class, Index);
for (Word = Proto->Configs; for (Word = Proto->Configs;
Word < Proto->Configs + WERDS_PER_CONFIG_VEC; *Word++ = 0); Word < Proto->Configs + WERDS_PER_CONFIG_VEC; *Word++ = 0);
@ -417,8 +415,8 @@ AddProtoToClassPruner (PROTO Proto, CLASS_ID ClassId, INT_TEMPLATES Templates)
TABLE_FILLER TableFiller; TABLE_FILLER TableFiller;
FILL_SPEC FillSpec; FILL_SPEC FillSpec;
ClassIndex = IndexForClassId (Templates, ClassId); ClassIndex = Templates->IndexFor[ClassId];
Pruner = CPrunerFor (Templates, ClassIndex); Pruner = Templates->ClassPruner [CPrunerIdFor (ClassIndex)];
WordIndex = CPrunerWordIndexFor (ClassIndex); WordIndex = CPrunerWordIndexFor (ClassIndex);
ClassMask = CPrunerMaskFor (MAX_LEVEL, ClassIndex); ClassMask = CPrunerMaskFor (MAX_LEVEL, ClassIndex);
@ -455,29 +453,29 @@ void AddProtoToProtoPruner(PROTO Proto, int ProtoId, INT_CLASS Class) {
int Index; int Index;
PROTO_SET ProtoSet; PROTO_SET ProtoSet;
if (ProtoId >= NumIntProtosIn (Class)) if (ProtoId >= Class->NumProtos)
cprintf ("AddProtoToProtoPruner:assert failed: %d < %d", cprintf ("AddProtoToProtoPruner:assert failed: %d < %d",
ProtoId, NumIntProtosIn (Class)); ProtoId, Class->NumProtos);
assert (ProtoId < NumIntProtosIn (Class)); assert (ProtoId < Class->NumProtos);
Index = IndexForProto (ProtoId); Index = IndexForProto (ProtoId);
ProtoSet = ProtoSetIn (Class, SetForProto (ProtoId)); ProtoSet = Class->ProtoSets[SetForProto (ProtoId)];
Angle = ProtoAngle (Proto); Angle = Proto->Angle;
FillPPCircularBits (ProtoSet->ProtoPruner[PRUNER_ANGLE], Index, FillPPCircularBits (ProtoSet->ProtoPruner[PRUNER_ANGLE], Index,
Angle + ANGLE_SHIFT, PPAnglePad / 360.0); Angle + ANGLE_SHIFT, PPAnglePad / 360.0);
Angle *= 2.0 * PI; Angle *= 2.0 * PI;
Length = ProtoLength (Proto); Length = Proto->Length;
X = ProtoX (Proto) + X_SHIFT; X = Proto->X + X_SHIFT;
Pad = max (fabs (cos (Angle)) * (Length / 2.0 + Pad = max (fabs (cos (Angle)) * (Length / 2.0 +
PPEndPad * GetPicoFeatureLength ()), PPEndPad * GetPicoFeatureLength ()),
fabs (sin (Angle)) * (PPSidePad * GetPicoFeatureLength ())); fabs (sin (Angle)) * (PPSidePad * GetPicoFeatureLength ()));
FillPPLinearBits (ProtoSet->ProtoPruner[PRUNER_X], Index, X, Pad); FillPPLinearBits (ProtoSet->ProtoPruner[PRUNER_X], Index, X, Pad);
Y = ProtoY (Proto) + Y_SHIFT; Y = Proto->Y + Y_SHIFT;
Pad = max (fabs (sin (Angle)) * (Length / 2.0 + Pad = max (fabs (sin (Angle)) * (Length / 2.0 +
PPEndPad * GetPicoFeatureLength ()), PPEndPad * GetPicoFeatureLength ()),
fabs (cos (Angle)) * (PPSidePad * GetPicoFeatureLength ())); fabs (cos (Angle)) * (PPSidePad * GetPicoFeatureLength ()));
@ -586,13 +584,13 @@ void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class) {
int TotalLength; int TotalLength;
for (ProtoId = 0, TotalLength = 0; for (ProtoId = 0, TotalLength = 0;
ProtoId < NumIntProtosIn (Class); ProtoId++) ProtoId < Class->NumProtos; ProtoId++)
if (test_bit (Config, ProtoId)) { if (test_bit (Config, ProtoId)) {
Proto = ProtoForProtoId (Class, ProtoId); Proto = ProtoForProtoId (Class, ProtoId);
SET_BIT (Proto->Configs, ConfigId); SET_BIT (Proto->Configs, ConfigId);
TotalLength += LengthForProtoId (Class, ProtoId); TotalLength += Class->ProtoLengths[ProtoId];
} }
LengthForConfigId (Class, ConfigId) = TotalLength; Class->ConfigLengths[ConfigId] = TotalLength;
} /* ConvertConfig */ } /* ConvertConfig */
@ -613,31 +611,31 @@ void ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class) {
INT_PROTO P; INT_PROTO P;
FLOAT32 Param; FLOAT32 Param;
assert (ProtoId < NumIntProtosIn (Class)); assert (ProtoId < Class->NumProtos);
P = ProtoForProtoId (Class, ProtoId); P = ProtoForProtoId (Class, ProtoId);
Param = CoefficientA (Proto) * 128; Param = Proto->A * 128;
P->A = TruncateParam (Param, -128, 127, NULL); P->A = TruncateParam (Param, -128, 127, NULL);
Param = -CoefficientB (Proto) * 256; Param = -Proto->B * 256;
P->B = TruncateParam (Param, 0, 255, NULL); P->B = TruncateParam (Param, 0, 255, NULL);
Param = CoefficientC (Proto) * 128; Param = Proto->C * 128;
P->C = TruncateParam (Param, -128, 127, NULL); P->C = TruncateParam (Param, -128, 127, NULL);
Param = ProtoAngle (Proto) * 256; Param = Proto->Angle * 256;
if (Param < 0 || Param >= 256) if (Param < 0 || Param >= 256)
P->Angle = 0; P->Angle = 0;
else else
P->Angle = (uinT8) Param; P->Angle = (uinT8) Param;
/* round proto length to nearest integer number of pico-features */ /* round proto length to nearest integer number of pico-features */
Param = (ProtoLength (Proto) / GetPicoFeatureLength ()) + 0.5; Param = (Proto->Length / GetPicoFeatureLength ()) + 0.5;
LengthForProtoId (Class, ProtoId) = TruncateParam (Param, 1, 255, NULL); Class->ProtoLengths[ProtoId] = TruncateParam (Param, 1, 255, NULL);
if (LearningDebugLevel >= 2) if (LearningDebugLevel >= 2)
cprintf ("Converted ffeat to (A=%d,B=%d,C=%d,L=%d)", cprintf ("Converted ffeat to (A=%d,B=%d,C=%d,L=%d)",
P->A, P->B, P->C, LengthForProtoId (Class, ProtoId)); P->A, P->B, P->C, Class->ProtoLengths[ProtoId]);
} /* ConvertProto */ } /* ConvertProto */
@ -665,12 +663,12 @@ INT_TEMPLATES CreateIntTemplates(CLASSES FloatProtos,
for (ClassId = 0; ClassId < target_unicharset.size(); ClassId++) { for (ClassId = 0; ClassId < target_unicharset.size(); ClassId++) {
FClass = &(FloatProtos[ClassId]); FClass = &(FloatProtos[ClassId]);
if (NumProtosIn (FClass) > 0) { if (FClass->NumProtos > 0) {
assert (UnusedClassIdIn (IntTemplates, ClassId)); assert (UnusedClassIdIn (IntTemplates, ClassId));
IClass = NewIntClass (NumProtosIn (FClass), NumConfigsIn (FClass)); IClass = NewIntClass (FClass->NumProtos, FClass->NumConfigs);
AddIntClass(IntTemplates, ClassId, IClass); AddIntClass(IntTemplates, ClassId, IClass);
for (ProtoId = 0; ProtoId < NumProtosIn (FClass); ProtoId++) { for (ProtoId = 0; ProtoId < FClass->NumProtos; ProtoId++) {
AddIntProto(IClass); AddIntProto(IClass);
ConvertProto (ProtoIn (FClass, ProtoId), ProtoId, IClass); ConvertProto (ProtoIn (FClass, ProtoId), ProtoId, IClass);
AddProtoToProtoPruner (ProtoIn (FClass, ProtoId), ProtoId, AddProtoToProtoPruner (ProtoIn (FClass, ProtoId), ProtoId,
@ -679,9 +677,9 @@ INT_TEMPLATES CreateIntTemplates(CLASSES FloatProtos,
IntTemplates); IntTemplates);
} }
for (ConfigId = 0; ConfigId < NumConfigsIn (FClass); ConfigId++) { for (ConfigId = 0; ConfigId < FClass->NumConfigs; ConfigId++) {
AddIntConfig(IClass); AddIntConfig(IClass);
ConvertConfig (ConfigIn (FClass, ConfigId), ConfigId, IClass); ConvertConfig (FClass->Configurations[ConfigId], ConfigId, IClass);
} }
} }
} }
@ -783,20 +781,20 @@ INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs) {
assert (MaxNumConfigs <= MAX_NUM_CONFIGS); assert (MaxNumConfigs <= MAX_NUM_CONFIGS);
Class = (INT_CLASS) Emalloc (sizeof (INT_CLASS_STRUCT)); Class = (INT_CLASS) Emalloc (sizeof (INT_CLASS_STRUCT));
NumProtoSetsIn (Class) = ((MaxNumProtos + PROTOS_PER_PROTO_SET - 1) / Class->NumProtoSets = ((MaxNumProtos + PROTOS_PER_PROTO_SET - 1) /
PROTOS_PER_PROTO_SET); PROTOS_PER_PROTO_SET);
assert (NumProtoSetsIn (Class) <= MAX_NUM_PROTO_SETS); assert(Class->NumProtoSets <= MAX_NUM_PROTO_SETS);
NumIntProtosIn (Class) = 0; Class->NumProtos = 0;
NumIntConfigsIn (Class) = 0; Class->NumConfigs = 0;
for (i = 0; i < NumProtoSetsIn (Class); i++) { for (i = 0; i < Class->NumProtoSets; i++) {
/* allocate space for a proto set, install in class, and initialize */ /* allocate space for a proto set, install in class, and initialize */
ProtoSet = (PROTO_SET) Emalloc (sizeof (PROTO_SET_STRUCT)); ProtoSet = (PROTO_SET) Emalloc (sizeof (PROTO_SET_STRUCT));
ProtoSetIn (Class, i) = ProtoSet; Class->ProtoSets[i] = ProtoSet;
for (Word = (uinT32 *) (ProtoPrunerFor (ProtoSet)); for (Word = (uinT32 *) (ProtoSet->ProtoPruner);
Word < (uinT32 *) (ProtoPrunerFor (ProtoSet)) + WERDS_PER_PP; Word < (uinT32 *) (ProtoSet->ProtoPruner) + WERDS_PER_PP;
*Word++ = 0); *Word++ = 0);
/* allocate space for the proto lengths and install in class */ /* allocate space for the proto lengths and install in class */
@ -814,8 +812,8 @@ void free_int_class( /*class to free */
INT_CLASS int_class) { INT_CLASS int_class) {
int i; int i;
for (i = 0; i < NumProtoSetsIn (int_class); i++) { for (i = 0; i < int_class->NumProtoSets; i++) {
Efree (ProtoSetIn (int_class, i)); Efree (int_class->ProtoSets[i]);
} }
Efree (int_class->ProtoLengths); Efree (int_class->ProtoLengths);
Efree(int_class); Efree(int_class);
@ -837,14 +835,14 @@ INT_TEMPLATES NewIntTemplates() {
int i; int i;
T = (INT_TEMPLATES) Emalloc (sizeof (INT_TEMPLATES_STRUCT)); T = (INT_TEMPLATES) Emalloc (sizeof (INT_TEMPLATES_STRUCT));
NumClassesIn (T) = 0; T->NumClasses = 0;
NumClassPrunersIn (T) = 0; T->NumClassPruners = 0;
/* initialize mapping tables */ /* initialize mapping tables */
for (i = 0; i <= MAX_CLASS_ID; i++) for (i = 0; i <= MAX_CLASS_ID; i++)
IndexForClassId (T, i) = ILLEGAL_CLASS; T->IndexFor[i] = ILLEGAL_CLASS;
for (i = 0; i < MAX_NUM_CLASSES; i++) for (i = 0; i < MAX_NUM_CLASSES; i++)
ClassIdForIndex (T, i) = NO_CLASS; T->ClassIdFor[i] = NO_CLASS;
return (T); return (T);
@ -855,9 +853,9 @@ INT_TEMPLATES NewIntTemplates() {
void free_int_templates(INT_TEMPLATES templates) { void free_int_templates(INT_TEMPLATES templates) {
int i; int i;
for (i = 0; i < NumClassesIn (templates); i++) for (i = 0; i < templates->NumClasses; i++)
free_int_class (ClassForIndex (templates, i)); free_int_class (templates->Class[i]);
for (i = 0; i < NumClassPrunersIn (templates); i++) for (i = 0; i < templates->NumClassPruners; i++)
Efree (templates->ClassPruner[i]); Efree (templates->ClassPruner[i]);
Efree(templates); Efree(templates);
} }
@ -921,7 +919,7 @@ INT_TEMPLATES ReadIntTemplates(FILE *File, BOOL8 swap) {
if (fread(&Templates->IndexFor[i], sizeof(CLASS_INDEX), 1, File) != 1) if (fread(&Templates->IndexFor[i], sizeof(CLASS_INDEX), 1, File) != 1)
cprintf("Bad read of inttemp!\n"); cprintf("Bad read of inttemp!\n");
} }
for (i = 0; i < NumClassesIn (Templates); ++i) { for (i = 0; i < Templates->NumClasses; ++i) {
if (fread(&Templates->ClassIdFor[i], sizeof(CLASS_ID), 1, File) != 1) if (fread(&Templates->ClassIdFor[i], sizeof(CLASS_ID), 1, File) != 1)
cprintf("Bad read of inttemp!\n"); cprintf("Bad read of inttemp!\n");
} }
@ -933,7 +931,7 @@ INT_TEMPLATES ReadIntTemplates(FILE *File, BOOL8 swap) {
} }
/* then read in the class pruners */ /* then read in the class pruners */
for (i = 0; i < NumClassPrunersIn (Templates); i++) { for (i = 0; i < Templates->NumClassPruners; i++) {
Pruner = (CLASS_PRUNER) Emalloc (sizeof (CLASS_PRUNER_STRUCT)); Pruner = (CLASS_PRUNER) Emalloc (sizeof (CLASS_PRUNER_STRUCT));
if ((nread = if ((nread =
fread ((char *) Pruner, 1, sizeof (CLASS_PRUNER_STRUCT), fread ((char *) Pruner, 1, sizeof (CLASS_PRUNER_STRUCT),
@ -954,7 +952,7 @@ INT_TEMPLATES ReadIntTemplates(FILE *File, BOOL8 swap) {
} }
/* then read in each class */ /* then read in each class */
for (i = 0; i < NumClassesIn (Templates); i++) { for (i = 0; i < Templates->NumClasses; i++) {
/* first read in the high level struct for the class */ /* first read in the high level struct for the class */
Class = (INT_CLASS) Emalloc (sizeof (INT_CLASS_STRUCT)); Class = (INT_CLASS) Emalloc (sizeof (INT_CLASS_STRUCT));
if (fread(&Class->NumProtos, sizeof(Class->NumProtos), 1, File) != 1 || if (fread(&Class->NumProtos, sizeof(Class->NumProtos), 1, File) != 1 ||
@ -978,7 +976,7 @@ INT_TEMPLATES ReadIntTemplates(FILE *File, BOOL8 swap) {
for (j = 0; j < MAX_NUM_CONFIGS; j++) for (j = 0; j < MAX_NUM_CONFIGS; j++)
reverse16 (&Class->ConfigLengths[j]); reverse16 (&Class->ConfigLengths[j]);
} }
ClassForIndex (Templates, i) = Class; Templates->Class[i] = Class;
/* then read in the proto lengths */ /* then read in the proto lengths */
Lengths = (uinT8 *) Emalloc (sizeof (uinT8) * Lengths = (uinT8 *) Emalloc (sizeof (uinT8) *
@ -990,7 +988,7 @@ INT_TEMPLATES ReadIntTemplates(FILE *File, BOOL8 swap) {
Class->ProtoLengths = Lengths; Class->ProtoLengths = Lengths;
/* then read in the proto sets */ /* then read in the proto sets */
for (j = 0; j < NumProtoSetsIn (Class); j++) { for (j = 0; j < Class->NumProtoSets; j++) {
ProtoSet = (PROTO_SET) Emalloc (sizeof (PROTO_SET_STRUCT)); ProtoSet = (PROTO_SET) Emalloc (sizeof (PROTO_SET_STRUCT));
if ((nread = if ((nread =
fread ((char *) ProtoSet, 1, sizeof (PROTO_SET_STRUCT), fread ((char *) ProtoSet, 1, sizeof (PROTO_SET_STRUCT),
@ -1005,7 +1003,7 @@ INT_TEMPLATES ReadIntTemplates(FILE *File, BOOL8 swap) {
for (y = 0; y < WERDS_PER_CONFIG_VEC; y++) for (y = 0; y < WERDS_PER_CONFIG_VEC; y++)
reverse32 (&ProtoSet->Protos[x].Configs[y]); reverse32 (&ProtoSet->Protos[x].Configs[y]);
} }
ProtoSetIn (Class, j) = ProtoSet; Class->ProtoSets[j] = ProtoSet;
} }
} }
return (Templates); return (Templates);
@ -1114,16 +1112,16 @@ void WriteIntTemplates(FILE *File, INT_TEMPLATES Templates,
fwrite(&Templates->IndexFor[0], sizeof(Templates->IndexFor[0]), fwrite(&Templates->IndexFor[0], sizeof(Templates->IndexFor[0]),
unicharset_size, File); unicharset_size, File);
fwrite(&Templates->ClassIdFor[0], sizeof(Templates->ClassIdFor[0]), fwrite(&Templates->ClassIdFor[0], sizeof(Templates->ClassIdFor[0]),
NumClassesIn(Templates), File); Templates->NumClasses, File);
/* then write out the class pruners */ /* then write out the class pruners */
for (i = 0; i < NumClassPrunersIn (Templates); i++) for (i = 0; i < Templates->NumClassPruners; i++)
fwrite(Templates->ClassPruner[i], fwrite(Templates->ClassPruner[i],
sizeof(CLASS_PRUNER_STRUCT), 1, File); sizeof(CLASS_PRUNER_STRUCT), 1, File);
/* then write out each class */ /* then write out each class */
for (i = 0; i < NumClassesIn(Templates); i++) { for (i = 0; i < Templates->NumClasses; i++) {
Class = ClassForIndex(Templates, i); Class = Templates->Class[i];
/* first write out the high level struct for the class */ /* first write out the high level struct for the class */
fwrite(&Class->NumProtos, sizeof(Class->NumProtos), 1, File); fwrite(&Class->NumProtos, sizeof(Class->NumProtos), 1, File);
@ -1138,8 +1136,8 @@ void WriteIntTemplates(FILE *File, INT_TEMPLATES Templates,
MaxNumIntProtosIn (Class), File); MaxNumIntProtosIn (Class), File);
/* then write out the proto sets */ /* then write out the proto sets */
for (j = 0; j < NumProtoSetsIn (Class); j++) for (j = 0; j < Class->NumProtoSets; j++)
fwrite ((char *) ProtoSetIn (Class, j), fwrite ((char *) Class->ProtoSets[j],
sizeof (PROTO_SET_STRUCT), 1, File); sizeof (PROTO_SET_STRUCT), 1, File);
} }
} /* WriteIntTemplates */ } /* WriteIntTemplates */
@ -1546,10 +1544,10 @@ FLOAT32 AnglePad, PROTO Proto, TABLE_FILLER * Filler)
int S1 = 0; int S1 = 0;
int S2 = 1; int S2 = 1;
Angle = ProtoAngle (Proto); Angle = Proto->Angle;
X = ProtoX (Proto); X = Proto->X;
Y = ProtoY (Proto); Y = Proto->Y;
HalfLength = ProtoLength (Proto) / 2.0; HalfLength = Proto->Length / 2.0;
Filler->AngleStart = CircBucketFor (Angle - AnglePad, AS, NB); Filler->AngleStart = CircBucketFor (Angle - AnglePad, AS, NB);
Filler->AngleEnd = CircBucketFor (Angle + AnglePad, AS, NB); Filler->AngleEnd = CircBucketFor (Angle + AnglePad, AS, NB);
@ -1753,14 +1751,14 @@ void RenderIntProto(void *window,
assert (ProtoId >= 0); assert (ProtoId >= 0);
assert (Class != NULL); assert (Class != NULL);
assert (ProtoId < NumIntProtosIn (Class)); assert (ProtoId < Class->NumProtos);
assert (Color != 0); assert (Color != 0);
c_line_color_index(window, Color); c_line_color_index(window, Color);
ProtoSet = ProtoSetIn (Class, SetForProto (ProtoId)); ProtoSet = Class->ProtoSets[SetForProto (ProtoId)];
ProtoSetIndex = IndexForProto (ProtoId); ProtoSetIndex = IndexForProto (ProtoId);
Proto = &(ProtoSet->Protos[ProtoSetIndex]); Proto = &(ProtoSet->Protos[ProtoSetIndex]);
Length = (LengthForProtoId (Class, ProtoId) * Length = (Class->ProtoLengths[ProtoId] *
GetPicoFeatureLength () * INT_CHAR_NORM_RANGE); GetPicoFeatureLength () * INT_CHAR_NORM_RANGE);
ProtoMask = PPrunerMaskFor (ProtoId); ProtoMask = PPrunerMaskFor (ProtoId);
ProtoWordIndex = PPrunerWordIndexFor (ProtoId); ProtoWordIndex = PPrunerWordIndexFor (ProtoId);

View File

@ -138,40 +138,22 @@ typedef INT_FEATURE_STRUCT INT_FEATURE_ARRAY[MAX_NUM_INT_FEATURES];
/**---------------------------------------------------------------------------- /**----------------------------------------------------------------------------
Macros Macros
----------------------------------------------------------------------------**/ ----------------------------------------------------------------------------**/
/* PROTO_SET access macros*/
#define ProtoPrunerFor(S) (S->ProtoPruner)
/* INT_CLASS access macros*/ #define MaxNumIntProtosIn(C) (C->NumProtoSets * PROTOS_PER_PROTO_SET)
#define NumIntProtosIn(C) ((C)->NumProtos)
#define NumProtoSetsIn(C) ((C)->NumProtoSets)
#define MaxNumIntProtosIn(C) (NumProtoSetsIn (C) * PROTOS_PER_PROTO_SET)
#define NumIntConfigsIn(C) ((C)->NumConfigs)
#define ProtoSetIn(C,I) ((C)->ProtoSets[I])
#define SetForProto(P) (P / PROTOS_PER_PROTO_SET) #define SetForProto(P) (P / PROTOS_PER_PROTO_SET)
#define IndexForProto(P) (P % PROTOS_PER_PROTO_SET) #define IndexForProto(P) (P % PROTOS_PER_PROTO_SET)
//#define IllegalProto(C,P) (P >= MaxNumIntProtosIn (C)) #define ProtoForProtoId(C,P) (&((C->ProtoSets[SetForProto (P)])-> \
#define ProtoForProtoId(C,P) (&((ProtoSetIn (C, SetForProto (P)))-> \
Protos [IndexForProto (P)])) Protos [IndexForProto (P)]))
#define LengthForProtoId(C,P) ((C)->ProtoLengths[P])
#define LengthForConfigId(C,c) ((C)->ConfigLengths[c])
#define PPrunerWordIndexFor(I) (((I) % PROTOS_PER_PROTO_SET) / \ #define PPrunerWordIndexFor(I) (((I) % PROTOS_PER_PROTO_SET) / \
PROTOS_PER_PP_WERD) PROTOS_PER_PP_WERD)
#define PPrunerBitIndexFor(I) ((I) % PROTOS_PER_PP_WERD) #define PPrunerBitIndexFor(I) ((I) % PROTOS_PER_PP_WERD)
#define PPrunerMaskFor(I) (1 << PPrunerBitIndexFor (I)) #define PPrunerMaskFor(I) (1 << PPrunerBitIndexFor (I))
/* INT_TEMPLATE access macros*/ #define MaxNumClassesIn(T) (T->NumClassPruners * CLASSES_PER_CP)
#define NumClassesIn(T) ((T)->NumClasses)
#define NumClassPrunersIn(T) ((T)->NumClassPruners)
#define MaxNumClassesIn(T) (NumClassPrunersIn (T) * CLASSES_PER_CP)
#define ClassIdForIndex(T,I) ((T)->ClassIdFor[I])
#define IndexForClassId(T,C) ((T)->IndexFor[C])
#define LegalClassId(C) ((C) > 0 && (C) <= MAX_CLASS_ID) #define LegalClassId(C) ((C) > 0 && (C) <= MAX_CLASS_ID)
#define UnusedClassIdIn(T,C) (IndexForClassId (T,C) == ILLEGAL_CLASS) #define UnusedClassIdIn(T,C) (T->IndexFor[C] == ILLEGAL_CLASS)
#define ClassForIndex(T,I) ((T)->Class[I]) #define ClassForClassId(T,C) (T->Class[(T->IndexFor[C])])
#define ClassForClassId(T,C) (ClassForIndex (T, IndexForClassId (T, C)))
#define ClassPrunersFor(T) ((T)->ClassPruner)
#define CPrunerIdFor(I) ((I) / CLASSES_PER_CP) #define CPrunerIdFor(I) ((I) / CLASSES_PER_CP)
#define CPrunerFor(T,I) ((T)->ClassPruner [CPrunerIdFor (I)])
#define CPrunerWordIndexFor(I) (((I) % CLASSES_PER_CP) / CLASSES_PER_CP_WERD) #define CPrunerWordIndexFor(I) (((I) % CLASSES_PER_CP) / CLASSES_PER_CP_WERD)
#define CPrunerBitIndexFor(I) (((I) % CLASSES_PER_CP) % CLASSES_PER_CP_WERD) #define CPrunerBitIndexFor(I) (((I) % CLASSES_PER_CP) % CLASSES_PER_CP_WERD)
#define CPrunerMaskFor(L,I) (((L)+1) << CPrunerBitIndexFor (I) * NUM_BITS_PER_CLASS) #define CPrunerMaskFor(L,I) (((L)+1) << CPrunerBitIndexFor (I) * NUM_BITS_PER_CLASS)

View File

@ -59,17 +59,17 @@ FEATURE_SET ExtractMicros(TBLOB *Blob, LINE_STATS *LineStats) {
iterate(Features) { iterate(Features) {
OldFeature = (MICROFEATURE) first_node (Features); OldFeature = (MICROFEATURE) first_node (Features);
Feature = NewFeature (&MicroFeatureDesc); Feature = NewFeature (&MicroFeatureDesc);
ParamOf (Feature, MFDirection) = OrientationOf (OldFeature); Feature->Params[MFDirection] = OldFeature[ORIENTATION];
ParamOf (Feature, MFXPosition) = CenterX (OldFeature); Feature->Params[MFXPosition] = OldFeature[XPOSITION];
ParamOf (Feature, MFYPosition) = CenterY (OldFeature); Feature->Params[MFYPosition] = OldFeature[YPOSITION];
ParamOf (Feature, MFLength) = LengthOf (OldFeature); Feature->Params[MFLength] = OldFeature[MFLENGTH];
// Bulge features should not be used // Bulge features should not be used
// anymore and are therefore set to 0. // anymore and are therefore set to 0.
// ParamOf (Feature, MFBulge1) = FirstBulgeOf (OldFeature); // ParamOf (Feature, MFBulge1) = FirstBulgeOf (OldFeature);
// ParamOf (Feature, MFBulge2) = SecondBulgeOf (OldFeature); // ParamOf (Feature, MFBulge2) = SecondBulgeOf (OldFeature);
ParamOf (Feature, MFBulge1) = 0.0f; Feature->Params[MFBulge1] = 0.0f;
ParamOf (Feature, MFBulge2) = 0.0f; Feature->Params[MFBulge2] = 0.0f;
AddFeature(FeatureSet, Feature); AddFeature(FeatureSet, Feature);
} }

View File

@ -47,13 +47,6 @@ typedef FLOAT32 *MICROFEATURE;
/**---------------------------------------------------------------------------- /**----------------------------------------------------------------------------
Macros Macros
----------------------------------------------------------------------------**/ ----------------------------------------------------------------------------**/
/* macros for accessing micro-feature parameters */
#define CenterX(M) ( (M)[XPOSITION] )
#define CenterY(M) ( (M)[YPOSITION] )
#define LengthOf(M) ( (M)[MFLENGTH] )
#define OrientationOf(M) ( (M)[ORIENTATION] )
#define FirstBulgeOf(M) ( (M)[FIRSTBULGE] )
#define SecondBulgeOf(M) ( (M)[SECONDBULGE] )
/* macros for accessing micro-feature lists */ /* macros for accessing micro-feature lists */
#define NextFeatureOf(L) ( (MICROFEATURE) first_node ( L ) ) #define NextFeatureOf(L) ( (MICROFEATURE) first_node ( L ) )

View File

@ -208,9 +208,9 @@ MFOUTLINE ConvertOutline(TESSLINE *Outline) {
EdgePoint->pos.y != NextPoint->pos.y) { EdgePoint->pos.y != NextPoint->pos.y) {
NewPoint = NewEdgePoint (); NewPoint = NewEdgePoint ();
ClearMark(NewPoint); ClearMark(NewPoint);
IsHidden (NewPoint) = is_hidden_edge (EdgePoint) ? TRUE : FALSE; NewPoint->Hidden = is_hidden_edge (EdgePoint) ? TRUE : FALSE;
XPositionOf (NewPoint) = EdgePoint->pos.x; NewPoint->Point.x = EdgePoint->pos.x;
YPositionOf (NewPoint) = EdgePoint->pos.y; NewPoint->Point.y = EdgePoint->pos.y;
MFOutline = push (MFOutline, NewPoint); MFOutline = push (MFOutline, NewPoint);
} }
EdgePoint = NextPoint; EdgePoint = NextPoint;
@ -219,24 +219,24 @@ MFOUTLINE ConvertOutline(TESSLINE *Outline) {
} }
/* use compressed version of outline */ /* use compressed version of outline */
else if (Outline->loop == NULL) { else if (Outline->loop == NULL) {
Xof (Position) = Xof (StartPosition) = Outline->start.x; Position.x = StartPosition.x = Outline->start.x;
Yof (Position) = Yof (StartPosition) = Outline->start.y; Position.y = StartPosition.y = Outline->start.y;
Vector = Outline->compactloop; Vector = Outline->compactloop;
do { do {
if (Vector->dx != 0 || Vector->dy != 0) { if (Vector->dx != 0 || Vector->dy != 0) {
NewPoint = NewEdgePoint (); NewPoint = NewEdgePoint ();
ClearMark(NewPoint); ClearMark(NewPoint);
/* all edges are visible */ /* all edges are visible */
IsHidden (NewPoint) = FALSE; NewPoint->Hidden = FALSE;
CopyPoint (Position, PositionOf (NewPoint)); CopyPoint (Position, NewPoint->Point);
MFOutline = push (MFOutline, NewPoint); MFOutline = push (MFOutline, NewPoint);
} }
Xof (Position) += Vector->dx; Position.x += Vector->dx;
Yof (Position) += Vector->dy; Position.y += Vector->dy;
Vector++; Vector++;
} }
while ((Xof (Position) != Xof (StartPosition)) || while (Position.x != StartPosition.x ||
(Yof (Position) != Yof (StartPosition))); (Position.y != StartPosition.y));
} }
else { /* use expanded version of outline */ else { /* use expanded version of outline */
StartPoint = Outline->loop; StartPoint = Outline->loop;
@ -249,10 +249,10 @@ MFOUTLINE ConvertOutline(TESSLINE *Outline) {
EdgePoint->pos.y != NextPoint->pos.y) { EdgePoint->pos.y != NextPoint->pos.y) {
NewPoint = NewEdgePoint (); NewPoint = NewEdgePoint ();
ClearMark(NewPoint); ClearMark(NewPoint);
IsHidden (NewPoint) = is_hidden_edge (EdgePoint) ? TRUE : FALSE; NewPoint->Hidden = is_hidden_edge (EdgePoint) ? TRUE : FALSE;
XPositionOf (NewPoint) = NewPoint->Point.x =
(EdgePoint->pos.x + BlobCenter.x) / REALSCALE; (EdgePoint->pos.x + BlobCenter.x) / REALSCALE;
YPositionOf (NewPoint) = NewPoint->Point.y =
(EdgePoint->pos.y + BlobCenter.y) / REALSCALE; (EdgePoint->pos.y + BlobCenter.y) / REALSCALE;
MFOutline = push (MFOutline, NewPoint); MFOutline = push (MFOutline, NewPoint);
} }
@ -344,8 +344,8 @@ void ComputeOutlineStats(LIST Outlines, OUTLINE_STATS *OutlineStats) {
Current = PointAt (EdgePoint); Current = PointAt (EdgePoint);
UpdateOutlineStats (OutlineStats, UpdateOutlineStats (OutlineStats,
XPositionOf (Last), YPositionOf (Last), Last->Point.x, Last->Point.y,
XPositionOf (Current), YPositionOf (Current)); Current->Point.x, Current->Point.y);
Last = Current; Last = Current;
EdgePoint = NextPointAfter (EdgePoint); EdgePoint = NextPointAfter (EdgePoint);
@ -388,14 +388,14 @@ void FilterEdgeNoise(MFOUTLINE Outline, FLOAT32 NoiseSegmentLength) {
Last = First; Last = First;
do { do {
Current = NextDirectionChange (Last); Current = NextDirectionChange (Last);
Length = DistanceBetween (PositionOf (PointAt (Current)), Length = DistanceBetween ((PointAt (Current)->Point),
PositionOf (PointAt (Last))); PointAt (Last)->Point);
if (Length >= NoiseSegmentLength) { if (Length >= NoiseSegmentLength) {
if (NumFound == 0) { if (NumFound == 0) {
NumFound = 1; NumFound = 1;
DirectionOfFirst = DirectionOf (PointAt (Last)); DirectionOfFirst = PointAt (Last)->Direction;
} }
else if (DirectionOfFirst != DirectionOf (PointAt (Last))) else if (DirectionOfFirst != PointAt (Last)->Direction)
break; break;
} }
Last = Current; Last = Current;
@ -410,10 +410,10 @@ void FilterEdgeNoise(MFOUTLINE Outline, FLOAT32 NoiseSegmentLength) {
First = Last; First = Last;
do { do {
Current = NextDirectionChange (Last); Current = NextDirectionChange (Last);
Length = DistanceBetween (PositionOf (PointAt (Current)), Length = DistanceBetween (PointAt (Current)->Point,
PositionOf (PointAt (Last))); PointAt (Last)->Point);
if (Length < NoiseSegmentLength) if (Length < NoiseSegmentLength)
ChangeDirection (Last, Current, PreviousDirectionOf (PointAt (Last))); ChangeDirection (Last, Current, PointAt (Last)->PreviousDirection);
Last = Current; Last = Current;
} }
@ -485,7 +485,7 @@ void FreeMFOutline(void *arg) { //MFOUTLINE Outline
Start = rest (Outline); Start = rest (Outline);
set_rest(Outline, NIL); set_rest(Outline, NIL);
while (Start != NULL) { while (Start != NULL) {
c_free_struct (first_node (Start), sizeof (MFEDGEPT), "MFEDGEPT"); free_struct (first_node (Start), sizeof (MFEDGEPT), "MFEDGEPT");
Start = pop (Start); Start = pop (Start);
} }
@ -577,7 +577,7 @@ MFEDGEPT *NewEdgePoint() {
** Exceptions: none ** Exceptions: none
** History: 7/21/89, DSJ, Created. ** History: 7/21/89, DSJ, Created.
*/ */
return ((MFEDGEPT *) c_alloc_struct (sizeof (MFEDGEPT), "MFEDGEPT")); return ((MFEDGEPT *) alloc_struct (sizeof (MFEDGEPT), "MFEDGEPT"));
} /* NewEdgePoint */ } /* NewEdgePoint */
@ -599,7 +599,7 @@ MFOUTLINE NextExtremity(MFOUTLINE EdgePoint) {
** History: 7/26/89, DSJ, Created. ** History: 7/26/89, DSJ, Created.
*/ */
EdgePoint = NextPointAfter (EdgePoint); EdgePoint = NextPointAfter (EdgePoint);
while (NotExtremity (PointAt (EdgePoint))) while (!PointAt (EdgePoint)->ExtremityMark)
EdgePoint = NextPointAfter (EdgePoint); EdgePoint = NextPointAfter (EdgePoint);
return (EdgePoint); return (EdgePoint);
@ -646,20 +646,20 @@ void NormalizeOutline(MFOUTLINE Outline,
do { do {
Current = PointAt (EdgePoint); Current = PointAt (EdgePoint);
YPositionOf (Current) = ScaleFactor * Current->Point.y = ScaleFactor *
(YPositionOf (Current) - (Current->Point.y -
BaselineAt (LineStats, XPositionOf (Current))); BaselineAt (LineStats, XPositionOf (Current)));
if (YPositionOf (Current) > NORMAL_X_HEIGHT) if (Current->Point.y > NORMAL_X_HEIGHT)
YPositionOf (Current) = NORMAL_X_HEIGHT + Current->Point.y = NORMAL_X_HEIGHT +
(YPositionOf (Current) - NORMAL_X_HEIGHT) / AscStretch; (Current->Point.y - NORMAL_X_HEIGHT) / AscStretch;
else if (YPositionOf (Current) < NORMAL_BASELINE) else if (Current->Point.y < NORMAL_BASELINE)
YPositionOf (Current) = NORMAL_BASELINE + Current->Point.y = NORMAL_BASELINE +
(YPositionOf (Current) - NORMAL_BASELINE) / DescStretch; (Current->Point.y - NORMAL_BASELINE) / DescStretch;
XPositionOf (Current) = ScaleFactor * Current->Point.x = ScaleFactor *
(XPositionOf (Current) - XOrigin); (Current->Point.x - XOrigin);
EdgePoint = NextPointAfter (EdgePoint); EdgePoint = NextPointAfter (EdgePoint);
} }
@ -787,10 +787,10 @@ void SmearExtremities(MFOUTLINE Outline, FLOAT32 XScale, FLOAT32 YScale) {
EdgePoint = Outline; EdgePoint = Outline;
do { do {
Current = PointAt (EdgePoint); Current = PointAt (EdgePoint);
if (IsExtremity (Current)) { if (Current->ExtremityMark) {
XPositionOf (Current) += Current->Point.x +=
UniformRandomNumber(MinXSmear, MaxXSmear); UniformRandomNumber(MinXSmear, MaxXSmear);
YPositionOf (Current) += Current->Point.y +=
UniformRandomNumber(MinYSmear, MaxYSmear); UniformRandomNumber(MinYSmear, MaxYSmear);
} }
@ -823,9 +823,9 @@ void ChangeDirection(MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction) {
MFOUTLINE Current; MFOUTLINE Current;
for (Current = Start; Current != End; Current = NextPointAfter (Current)) for (Current = Start; Current != End; Current = NextPointAfter (Current))
DirectionOf (PointAt (Current)) = Direction; PointAt (Current)->Direction = Direction;
PreviousDirectionOf (PointAt (End)) = Direction; PointAt (End)->PreviousDirection = Direction;
} /* ChangeDirection */ } /* ChangeDirection */
@ -859,10 +859,10 @@ void CharNormalizeOutline(MFOUTLINE Outline,
Current = First; Current = First;
do { do {
CurrentPoint = PointAt (Current); CurrentPoint = PointAt (Current);
XPositionOf (CurrentPoint) = CurrentPoint->Point.x =
(XPositionOf (CurrentPoint) - XCenter) * XScale; (CurrentPoint->Point.x - XCenter) * XScale;
YPositionOf (CurrentPoint) = CurrentPoint->Point.y =
(YPositionOf (CurrentPoint) - YCenter) * YScale; (CurrentPoint->Point.y - YCenter) * YScale;
Current = NextPointAfter (Current); Current = NextPointAfter (Current);
} }
@ -1029,11 +1029,11 @@ MFOUTLINE NextDirectionChange(MFOUTLINE EdgePoint) {
*/ */
DIRECTION InitialDirection; DIRECTION InitialDirection;
InitialDirection = DirectionOf (PointAt (EdgePoint)); InitialDirection = PointAt (EdgePoint)->Direction;
do do
EdgePoint = NextPointAfter (EdgePoint); EdgePoint = NextPointAfter (EdgePoint);
while (DirectionOf (PointAt (EdgePoint)) == InitialDirection); while (PointAt (EdgePoint)->Direction == InitialDirection);
return (EdgePoint); return (EdgePoint);
} /* NextDirectionChange */ } /* NextDirectionChange */

View File

@ -111,17 +111,17 @@ extern int NormMethod;
#define MakeOutlineCircular(O) (set_rest (last (O), (O))) #define MakeOutlineCircular(O) (set_rest (last (O), (O)))
/* macros for manipulating micro-feature outline edge points */ /* macros for manipulating micro-feature outline edge points */
#define PositionOf(P) ((P)->Point) //#define PositionOf(P) ((P)->Point)
#define XPositionOf(P) (PositionOf(P).x) //#define XPositionOf(P) ((P)->Point.x)
#define YPositionOf(P) (PositionOf(P).y) //#define YPositionOf(P) ((P)->Point.y)
#define DirectionOf(P) ((P)->Direction) //#define DirectionOf(P) ((P)->Direction)
#define PreviousDirectionOf(P) ((P)->PreviousDirection) //#define PreviousDirectionOf(P) ((P)->PreviousDirection)
#define ClearMark(P) ((P)->ExtremityMark = FALSE) #define ClearMark(P) ((P)->ExtremityMark = FALSE)
#define MarkPoint(P) ((P)->ExtremityMark = TRUE) #define MarkPoint(P) ((P)->ExtremityMark = TRUE)
#define IsExtremity(P) ((P)->ExtremityMark) //#define IsExtremity(P) ((P)->ExtremityMark)
#define NotExtremity(P) (!IsExtremity(P)) //#define NotExtremity(P) (!(P->ExtremityMark))
#define IsVisible(E) (! IsHidden(E)) //#define IsVisible(E) (! (E->Hidden))
#define IsHidden(E) ((E)->Hidden) //#define IsHidden(E) ((E)->Hidden)
/**---------------------------------------------------------------------------- /**----------------------------------------------------------------------------
Public Function Prototypes Public Function Prototypes

View File

@ -248,25 +248,26 @@ void ComputeBulges(MFOUTLINE Start, MFOUTLINE End, MICROFEATURE MicroFeature) {
/* check for simple case */ /* check for simple case */
if (End == NextPointAfter (Start)) if (End == NextPointAfter (Start))
FirstBulgeOf (MicroFeature) = SecondBulgeOf (MicroFeature) = 0; MicroFeature[FIRSTBULGE] = MicroFeature[SECONDBULGE] = 0;
else { else {
Origin = PointAt (Start); Origin = PointAt (Start);
InitMatrix(&Matrix); InitMatrix(&Matrix);
RotateMatrix (&Matrix, OrientationOf (MicroFeature) * -2.0 * PI); RotateMatrix (&Matrix, MicroFeature[ORIENTATION] * -2.0 * PI);
TranslateMatrix (&Matrix, -XPositionOf (Origin), -YPositionOf (Origin)); TranslateMatrix (&Matrix, -Origin->Point.x, -Origin->Point.y);
SegmentEnd = Start; SegmentEnd = Start;
FillPoint (CurrentPoint, 0, 0); FillPoint (CurrentPoint, 0, 0);
BulgePosition = LengthOf (MicroFeature) / 3; BulgePosition = MicroFeature[MFLENGTH] / 3;
CopyPoint(CurrentPoint, LastPoint); CopyPoint(CurrentPoint, LastPoint);
while (Xof (CurrentPoint) < BulgePosition) { while (CurrentPoint.x < BulgePosition) {
SegmentStart = SegmentEnd; SegmentStart = SegmentEnd;
SegmentEnd = NextPointAfter (SegmentStart); SegmentEnd = NextPointAfter (SegmentStart);
CopyPoint(CurrentPoint, LastPoint); CopyPoint(CurrentPoint, LastPoint);
MapPoint (&Matrix, PositionOf (PointAt (SegmentEnd)), CurrentPoint);
MapPoint (&Matrix, PointAt (SegmentEnd)->Point, CurrentPoint);
} }
FirstBulgeOf (MicroFeature) = MicroFeature[FIRSTBULGE] =
XIntersectionOf(LastPoint, CurrentPoint, BulgePosition); XIntersectionOf(LastPoint, CurrentPoint, BulgePosition);
BulgePosition *= 2; BulgePosition *= 2;
@ -274,21 +275,19 @@ void ComputeBulges(MFOUTLINE Start, MFOUTLINE End, MICROFEATURE MicroFeature) {
// Prevents from copying the points before computing the bulge if // Prevents from copying the points before computing the bulge if
// CurrentPoint will not change. (Which would cause to output nan // CurrentPoint will not change. (Which would cause to output nan
// for the SecondBulge.) // for the SecondBulge.)
if (Xof (CurrentPoint) < BulgePosition) if (CurrentPoint.x < BulgePosition)
CopyPoint(CurrentPoint, LastPoint); CopyPoint(CurrentPoint, LastPoint);
while (Xof (CurrentPoint) < BulgePosition) { while (CurrentPoint.x < BulgePosition) {
SegmentStart = SegmentEnd; SegmentStart = SegmentEnd;
SegmentEnd = NextPointAfter (SegmentStart); SegmentEnd = NextPointAfter (SegmentStart);
CopyPoint(CurrentPoint, LastPoint); CopyPoint(CurrentPoint, LastPoint);
MapPoint (&Matrix, PositionOf (PointAt (SegmentEnd)), CurrentPoint); MapPoint (&Matrix, PointAt (SegmentEnd)->Point, CurrentPoint);
} }
SecondBulgeOf (MicroFeature) = MicroFeature[SECONDBULGE] =
XIntersectionOf(LastPoint, CurrentPoint, BulgePosition); XIntersectionOf(LastPoint, CurrentPoint, BulgePosition);
FirstBulgeOf (MicroFeature) /= BULGENORMALIZER * MicroFeature[FIRSTBULGE] /= BULGENORMALIZER * MicroFeature[MFLENGTH];
LengthOf(MicroFeature); MicroFeature[SECONDBULGE] /= BULGENORMALIZER * MicroFeature[MFLENGTH];
SecondBulgeOf (MicroFeature) /= BULGENORMALIZER *
LengthOf(MicroFeature);
} }
} /* ComputeBulges */ } /* ComputeBulges */
@ -315,8 +314,8 @@ FLOAT32 ComputeOrientation(MFEDGEPT *Start, MFEDGEPT *End) {
*/ */
FLOAT32 Orientation; FLOAT32 Orientation;
Orientation = NormalizeAngle (AngleFrom (PositionOf (Start), Orientation = NormalizeAngle (AngleFrom (Start->Point,
PositionOf (End))); End->Point));
/* ensure that round-off errors do not put circular param out of range */ /* ensure that round-off errors do not put circular param out of range */
if ((Orientation < 0) || (Orientation >= 1)) if ((Orientation < 0) || (Orientation >= 1))
@ -389,11 +388,11 @@ MICROFEATURE ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End) {
P2 = PointAt (End); P2 = PointAt (End);
NewFeature = NewMicroFeature (); NewFeature = NewMicroFeature ();
CenterX (NewFeature) = AverageOf (XPositionOf (P1), XPositionOf (P2)); NewFeature[XPOSITION] = AverageOf (P1->Point.x, P2->Point.x);
CenterY (NewFeature) = AverageOf (YPositionOf (P1), YPositionOf (P2)); NewFeature[YPOSITION] = AverageOf (P1->Point.y, P2->Point.y);
LengthOf (NewFeature) = DistanceBetween (PositionOf (P1), PositionOf (P2)); NewFeature[MFLENGTH] = DistanceBetween (P1->Point, P2->Point);
OrientationOf (NewFeature) = NewFeature[ORIENTATION] =
NormalizedAngleFrom (&(PositionOf (P1)), &(PositionOf (P2)), 1.0); NormalizedAngleFrom (&((P1)->Point), &((P2)->Point), 1.0);
ComputeBulges(Start, End, NewFeature); ComputeBulges(Start, End, NewFeature);
return (NewFeature); return (NewFeature);
} /* ExtractMicroFeature */ } /* ExtractMicroFeature */
@ -424,14 +423,14 @@ void SmearBulges(MICROFEATURES MicroFeatures, FLOAT32 XScale, FLOAT32 YScale) {
iterate(MicroFeatures) { iterate(MicroFeatures) {
MicroFeature = NextFeatureOf (MicroFeatures); MicroFeature = NextFeatureOf (MicroFeatures);
Cos = fabs (cos (2.0 * PI * OrientationOf (MicroFeature))); Cos = fabs (cos (2.0 * PI * MicroFeature[ORIENTATION]));
Sin = fabs (sin (2.0 * PI * OrientationOf (MicroFeature))); Sin = fabs (sin (2.0 * PI * MicroFeature[ORIENTATION]));
Scale = YScale * Cos + XScale * Sin; Scale = YScale * Cos + XScale * Sin;
MinSmear = -0.5 * Scale / (BULGENORMALIZER * LengthOf (MicroFeature)); MinSmear = -0.5 * Scale / (BULGENORMALIZER * MicroFeature[MFLENGTH]);
MaxSmear = 0.5 * Scale / (BULGENORMALIZER * LengthOf (MicroFeature)); MaxSmear = 0.5 * Scale / (BULGENORMALIZER * MicroFeature[MFLENGTH]);
FirstBulgeOf (MicroFeature) += UniformRandomNumber (MinSmear, MaxSmear); MicroFeature[FIRSTBULGE] += UniformRandomNumber (MinSmear, MaxSmear);
SecondBulgeOf (MicroFeature) += UniformRandomNumber (MinSmear, MaxSmear); MicroFeature[SECONDBULGE] += UniformRandomNumber (MinSmear, MaxSmear);
} }
} /* SmearBulges */ } /* SmearBulges */

View File

@ -46,7 +46,7 @@ FLOAT32 ActualOutlineLength(FEATURE Feature) {
** Exceptions: none ** Exceptions: none
** History: Thu Dec 20 14:50:57 1990, DSJ, Created. ** History: Thu Dec 20 14:50:57 1990, DSJ, Created.
*/ */
return (ParamOf (Feature, CharNormLength) * LENGTH_COMPRESSION); return (Feature->Params[CharNormLength] * LENGTH_COMPRESSION);
} /* ActualOutlineLength */ } /* ActualOutlineLength */
@ -106,11 +106,11 @@ FEATURE_SET ExtractCharNormFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
ExtractIntFeat(Blob, blfeatures, cnfeatures, &FXInfo); ExtractIntFeat(Blob, blfeatures, cnfeatures, &FXInfo);
Baseline = BaselineAt (LineStats, FXInfo.Xmean); Baseline = BaselineAt (LineStats, FXInfo.Xmean);
Scale = ComputeScaleFactor (LineStats); Scale = ComputeScaleFactor (LineStats);
ParamOf (Feature, CharNormY) = (FXInfo.Ymean - Baseline) * Scale; Feature->Params[CharNormY] = (FXInfo.Ymean - Baseline) * Scale;
ParamOf (Feature, CharNormLength) = Feature->Params[CharNormLength] =
FXInfo.Length * Scale / LENGTH_COMPRESSION; FXInfo.Length * Scale / LENGTH_COMPRESSION;
ParamOf (Feature, CharNormRx) = FXInfo.Rx * Scale; Feature->Params[CharNormRx] = FXInfo.Rx * Scale;
ParamOf (Feature, CharNormRy) = FXInfo.Ry * Scale; Feature->Params[CharNormRy] = FXInfo.Ry * Scale;
/*---------Debug--------------------------------------------------* /*---------Debug--------------------------------------------------*
File = fopen ("f:/ims/debug/nfFeatSet.logCPP", "r"); File = fopen ("f:/ims/debug/nfFeatSet.logCPP", "r");

View File

@ -97,12 +97,12 @@ FLOAT32 ComputeNormMatch(CLASS_ID ClassId, FEATURE Feature, BOOL8 DebugMatch) {
/* handle requests for classification as noise */ /* handle requests for classification as noise */
if (ClassId == NO_CLASS) { if (ClassId == NO_CLASS) {
/* kludge - clean up constants and make into control knobs later */ /* kludge - clean up constants and make into control knobs later */
Match = (ParamOf (Feature, CharNormLength) * Match = (Feature->Params[CharNormLength] *
ParamOf (Feature, CharNormLength) * 500.0 + Feature->Params[CharNormLength] * 500.0 +
ParamOf (Feature, CharNormRx) * Feature->Params[CharNormRx] *
ParamOf (Feature, CharNormRx) * 8000.0 + Feature->Params[CharNormRx] * 8000.0 +
ParamOf (Feature, CharNormRy) * Feature->Params[CharNormRy] *
ParamOf (Feature, CharNormRy) * 8000.0); Feature->Params[CharNormRy] * 8000.0);
return (1.0 - NormEvidenceOf (Match)); return (1.0 - NormEvidenceOf (Match));
} }
@ -117,9 +117,9 @@ FLOAT32 ComputeNormMatch(CLASS_ID ClassId, FEATURE Feature, BOOL8 DebugMatch) {
ProtoId = 0; ProtoId = 0;
iterate(Protos) { iterate(Protos) {
Proto = (PROTOTYPE *) first_node (Protos); Proto = (PROTOTYPE *) first_node (Protos);
Delta = ParamOf (Feature, CharNormY) - Proto->Mean[CharNormY]; Delta = Feature->Params[CharNormY] - Proto->Mean[CharNormY];
Match = Delta * Delta * Proto->Weight.Elliptical[CharNormY]; Match = Delta * Delta * Proto->Weight.Elliptical[CharNormY];
Delta = ParamOf (Feature, CharNormRx) - Proto->Mean[CharNormRx]; Delta = Feature->Params[CharNormRx] - Proto->Mean[CharNormRx];
Match += Delta * Delta * Proto->Weight.Elliptical[CharNormRx]; Match += Delta * Delta * Proto->Weight.Elliptical[CharNormRx];
if (Match < BestMatch) if (Match < BestMatch)
@ -242,8 +242,8 @@ void PrintNormMatch(FILE *File,
FLOAT32 TotalMatch; FLOAT32 TotalMatch;
for (i = 0, TotalMatch = 0.0; i < NumParams; i++) { for (i = 0, TotalMatch = 0.0; i < NumParams; i++) {
ParamMatch = ((ParamOf (Feature, i) - Mean (Proto, i)) / ParamMatch = (Feature->Params[i] - Mean (Proto, i)) /
StandardDeviation (Proto, i)); StandardDeviation (Proto, i);
fprintf (File, " %6.1f", ParamMatch); fprintf (File, " %6.1f", ParamMatch);

View File

@ -35,25 +35,4 @@ void FreeNormProtos();
void InitNormProtoVars(); void InitNormProtoVars();
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* normmatch.c *
FLOAT32 ComputeNormMatch
_ARGS((CLASS_ID ClassId,
FEATURE Feature,
BOOL8 DebugMatch));
void GetNormProtos
_ARGS((void));
void InitNormProtoVars
_ARGS((void));
#undef _ARGS
*/
#endif #endif

View File

@ -43,13 +43,13 @@ BOOL8 AddFeature(FEATURE_SET FeatureSet, FEATURE Feature) {
** Exceptions: none ** Exceptions: none
** History: Tue May 22 17:22:23 1990, DSJ, Created. ** History: Tue May 22 17:22:23 1990, DSJ, Created.
*/ */
if (NumFeaturesIn (FeatureSet) >= MaxNumFeaturesIn (FeatureSet)) { if (FeatureSet->NumFeatures >= FeatureSet->MaxNumFeatures) {
FreeFeature(Feature); FreeFeature(Feature);
return (FALSE); return (FALSE);
} }
FeatureIn (FeatureSet, NumFeaturesIn (FeatureSet)) = Feature; FeatureSet->Features[FeatureSet->NumFeatures] = Feature;
NumFeaturesIn (FeatureSet)++; FeatureSet->NumFeatures++;
return (TRUE); return (TRUE);
} /* AddFeature */ } /* AddFeature */
@ -83,7 +83,7 @@ void FreeFeature(FEATURE Feature) {
*/ */
if (Feature) { if (Feature) {
c_free_struct (Feature, sizeof (FEATURE_STRUCT) c_free_struct (Feature, sizeof (FEATURE_STRUCT)
+ sizeof (FLOAT32) * (NumParamsIn (Feature) - 1), + sizeof (FLOAT32) * (Feature->Type->NumParams - 1),
"sizeof(FEATURE_STRUCT)+sizeof(FLOAT32)*(NumParamsIn(Feature)-1)"); "sizeof(FEATURE_STRUCT)+sizeof(FLOAT32)*(NumParamsIn(Feature)-1)");
} }
@ -106,8 +106,8 @@ void FreeFeatureSet(FEATURE_SET FeatureSet) {
int i; int i;
if (FeatureSet) { if (FeatureSet) {
for (i = 0; i < NumFeaturesIn (FeatureSet); i++) for (i = 0; i < FeatureSet->NumFeatures; i++)
FreeFeature (FeatureIn (FeatureSet, i)); FreeFeature (FeatureSet->Features[i]);
memfree(FeatureSet); memfree(FeatureSet);
} }
} /* FreeFeatureSet */ } /* FreeFeatureSet */
@ -127,11 +127,11 @@ FEATURE NewFeature(FEATURE_DESC FeatureDesc) {
*/ */
FEATURE Feature; FEATURE Feature;
Feature = (FEATURE) c_alloc_struct (sizeof (FEATURE_STRUCT) + Feature = (FEATURE) alloc_struct (sizeof (FEATURE_STRUCT) +
(FeatureDesc->NumParams - 1) * (FeatureDesc->NumParams - 1) *
sizeof (FLOAT32), sizeof (FLOAT32),
"sizeof(FEATURE_STRUCT)+sizeof(FLOAT32)*(NumParamsIn(Feature)-1)"); "sizeof(FEATURE_STRUCT)+sizeof(FLOAT32)*(NumParamsIn(Feature)-1)");
TypeOf (Feature) = FeatureDesc; Feature->Type = FeatureDesc;
return (Feature); return (Feature);
} /* NewFeature */ } /* NewFeature */
@ -153,8 +153,8 @@ FEATURE_SET NewFeatureSet(int NumFeatures) {
FeatureSet = (FEATURE_SET) Emalloc (sizeof (FEATURE_SET_STRUCT) + FeatureSet = (FEATURE_SET) Emalloc (sizeof (FEATURE_SET_STRUCT) +
(NumFeatures - 1) * sizeof (FEATURE)); (NumFeatures - 1) * sizeof (FEATURE));
MaxNumFeaturesIn (FeatureSet) = NumFeatures; FeatureSet->MaxNumFeatures = NumFeatures;
NumFeaturesIn (FeatureSet) = 0; FeatureSet->NumFeatures = 0;
return (FeatureSet); return (FeatureSet);
} /* NewFeatureSet */ } /* NewFeatureSet */
@ -181,8 +181,8 @@ FEATURE ReadFeature(FILE *File, FEATURE_DESC FeatureDesc) {
int i; int i;
Feature = NewFeature (FeatureDesc); Feature = NewFeature (FeatureDesc);
for (i = 0; i < NumParamsIn (Feature); i++) { for (i = 0; i < Feature->Type->NumParams; i++) {
if (fscanf (File, "%f", &(ParamOf (Feature, i))) != 1) if (fscanf (File, "%f", &(Feature->Params[i])) != 1)
DoError (ILLEGAL_FEATURE_PARAM, "Illegal feature parameter spec"); DoError (ILLEGAL_FEATURE_PARAM, "Illegal feature parameter spec");
} }
return (Feature); return (Feature);
@ -241,8 +241,8 @@ void WriteFeature(FILE *File, FEATURE Feature) {
*/ */
int i; int i;
for (i = 0; i < NumParamsIn (Feature); i++) for (i = 0; i < Feature->Type->NumParams; i++)
fprintf (File, " %12g", ParamOf (Feature, i)); fprintf (File, " %12g", Feature->Params[i]);
fprintf (File, "\n"); fprintf (File, "\n");
} /* WriteFeature */ } /* WriteFeature */
@ -266,9 +266,9 @@ void WriteFeatureSet(FILE *File, FEATURE_SET FeatureSet) {
int i; int i;
if (FeatureSet) { if (FeatureSet) {
fprintf (File, "%d\n", NumFeaturesIn (FeatureSet)); fprintf (File, "%d\n", FeatureSet->NumFeatures);
for (i = 0; i < NumFeaturesIn (FeatureSet); i++) for (i = 0; i < FeatureSet->NumFeatures; i++)
WriteFeature (File, FeatureIn (FeatureSet, i)); WriteFeature (File, FeatureSet->Features[i]);
} }
} /* WriteFeatureSet */ } /* WriteFeatureSet */

View File

@ -121,28 +121,6 @@ FEATURE_DESC_STRUCT Name = { \
((NL) + (NC)), NL, NC, Min, Max, LN, SN, PN}; ((NL) + (NC)), NL, NC, Min, Max, LN, SN, PN};
#define DefineFeatureExt(Name, E, IEV) FEATURE_EXT_STRUCT Name = {E, IEV}; #define DefineFeatureExt(Name, E, IEV) FEATURE_EXT_STRUCT Name = {E, IEV};
/*----------------------------------------------------------------------
Macros for accessing features
----------------------------------------------------------------------*/
#define TypeOf(Feature) ((Feature)->Type)
#define ParamOf(Feature, N) ((Feature)->Params[N])
#define NumParamsIn(Feature) (TypeOf (Feature) -> NumParams)
/*----------------------------------------------------------------------
Macros for accessing feature sets
----------------------------------------------------------------------*/
#define NumFeaturesIn(Set) ((Set)->NumFeatures)
#define MaxNumFeaturesIn(Set) ((Set)->MaxNumFeatures)
#define FeatureIn(Set, N) ((Set)->Features[N])
/*----------------------------------------------------------------------
Macros for accessing feature descriptions
----------------------------------------------------------------------*/
#define ShortNameOf(FeatDesc) ((FeatDesc)->ShortName)
#define LongNameOf(FeatDesc) ((FeatDesc)->LongName)
#define ExtractUsing(FeatDesc) (*(FeatDesc)->Extractor)
#define InitFXVarsUsing(FD) (*(FD)->InitExtractorVars)
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
Generic routines that work for all feature types Generic routines that work for all feature types
----------------------------------------------------------------------*/ ----------------------------------------------------------------------*/

View File

@ -170,10 +170,10 @@ void AddOutlineFeatureToSet(FPOINT *Start,
FEATURE Feature; FEATURE Feature;
Feature = NewFeature (&OutlineFeatDesc); Feature = NewFeature (&OutlineFeatDesc);
ParamOf (Feature, OutlineFeatDir) = NormalizedAngleFrom (Start, End, 1.0); Feature->Params[OutlineFeatDir] = NormalizedAngleFrom (Start, End, 1.0);
ParamOf (Feature, OutlineFeatX) = AverageOf (Xof (*Start), Xof (*End)); Feature->Params[OutlineFeatX] = AverageOf (Start->x, End->x);
ParamOf (Feature, OutlineFeatY) = AverageOf (Yof (*Start), Yof (*End)); Feature->Params[OutlineFeatY] = AverageOf (Start->y, End->y);
ParamOf (Feature, OutlineFeatLength) = DistanceBetween (*Start, *End); Feature->Params[OutlineFeatLength] = DistanceBetween (*Start, *End);
AddFeature(FeatureSet, Feature); AddFeature(FeatureSet, Feature);
} /* AddOutlineFeatureToSet */ } /* AddOutlineFeatureToSet */
@ -206,7 +206,7 @@ void ConvertToOutlineFeatures(MFOUTLINE Outline, FEATURE_SET FeatureSet) {
First = Outline; First = Outline;
Next = First; Next = First;
do { do {
CopyPoint (PositionOf (PointAt (Next)), FeatureStart); CopyPoint (PointAt (Next)->Point, FeatureStart);
Next = NextPointAfter (Next); Next = NextPointAfter (Next);
/* note that an edge is hidden if the ending point of the edge is /* note that an edge is hidden if the ending point of the edge is
@ -214,8 +214,8 @@ void ConvertToOutlineFeatures(MFOUTLINE Outline, FEATURE_SET FeatureSet) {
the outlines is reversed when they are converted from the old the outlines is reversed when they are converted from the old
format. In the old format, a hidden edge is marked by the format. In the old format, a hidden edge is marked by the
starting point for that edge. */ starting point for that edge. */
if (IsVisible (PointAt (Next))) { if (! (PointAt (Next)->Hidden)) {
CopyPoint (PositionOf (PointAt (Next)), FeatureEnd); CopyPoint (PointAt (Next)->Point, FeatureEnd);
AddOutlineFeatureToSet(&FeatureStart, &FeatureEnd, FeatureSet); AddOutlineFeatureToSet(&FeatureStart, &FeatureEnd, FeatureSet);
} }
} }
@ -244,19 +244,19 @@ void NormalizeOutlineX(FEATURE_SET FeatureSet) {
FLOAT32 TotalWeight = 0.0; FLOAT32 TotalWeight = 0.0;
FLOAT32 Origin; FLOAT32 Origin;
if (NumFeaturesIn (FeatureSet) <= 0) if (FeatureSet->NumFeatures <= 0)
return; return;
for (i = 0; i < NumFeaturesIn (FeatureSet); i++) { for (i = 0; i < FeatureSet->NumFeatures; i++) {
Feature = FeatureIn (FeatureSet, i); Feature = FeatureSet->Features[i];
Length = ParamOf (Feature, OutlineFeatLength); Length = Feature->Params[OutlineFeatLength];
TotalX += ParamOf (Feature, OutlineFeatX) * Length; TotalX += Feature->Params[OutlineFeatX] * Length;
TotalWeight += Length; TotalWeight += Length;
} }
Origin = TotalX / TotalWeight; Origin = TotalX / TotalWeight;
for (i = 0; i < NumFeaturesIn (FeatureSet); i++) { for (i = 0; i < FeatureSet->NumFeatures; i++) {
Feature = FeatureIn (FeatureSet, i); Feature = FeatureSet->Features[i];
ParamOf (Feature, OutlineFeatX) -= Origin; Feature->Params[OutlineFeatX] -= Origin;
} }
} /* NormalizeOutlineX */ } /* NormalizeOutlineX */

View File

@ -200,23 +200,23 @@ void ConvertSegmentToPicoFeat(FPOINT *Start,
NumFeatures = 1; NumFeatures = 1;
/* compute vector for one pico feature */ /* compute vector for one pico feature */
Xof (Delta) = XDelta (*Start, *End) / NumFeatures; Delta.x = XDelta (*Start, *End) / NumFeatures;
Yof (Delta) = YDelta (*Start, *End) / NumFeatures; Delta.y = YDelta (*Start, *End) / NumFeatures;
/* compute position of first pico feature */ /* compute position of first pico feature */
Xof (Center) = Xof (*Start) + Xof (Delta) / 2.0; Center.x = Start->x + Delta.x / 2.0;
Yof (Center) = Yof (*Start) + Yof (Delta) / 2.0; Center.y = Start->y + Delta.y / 2.0;
/* compute each pico feature in segment and add to feature set */ /* compute each pico feature in segment and add to feature set */
for (i = 0; i < NumFeatures; i++) { for (i = 0; i < NumFeatures; i++) {
Feature = NewFeature (&PicoFeatDesc); Feature = NewFeature (&PicoFeatDesc);
ParamOf (Feature, PicoFeatDir) = Angle; Feature->Params[PicoFeatDir] = Angle;
ParamOf (Feature, PicoFeatX) = Xof (Center); Feature->Params[PicoFeatX] = Center.x;
ParamOf (Feature, PicoFeatY) = Yof (Center); Feature->Params[PicoFeatY] = Center.y;
AddFeature(FeatureSet, Feature); AddFeature(FeatureSet, Feature);
Xof (Center) += Xof (Delta); Center.x += Delta.x;
Yof (Center) += Yof (Delta); Center.y += Delta.y;
} }
} /* ConvertSegmentToPicoFeat */ } /* ConvertSegmentToPicoFeat */
@ -254,9 +254,9 @@ void ConvertToPicoFeatures2(MFOUTLINE Outline, FEATURE_SET FeatureSet) {
the outlines is reversed when they are converted from the old the outlines is reversed when they are converted from the old
format. In the old format, a hidden edge is marked by the format. In the old format, a hidden edge is marked by the
starting point for that edge. */ starting point for that edge. */
if (IsVisible (PointAt (Next))) if (!(PointAt (Next)->Hidden))
ConvertSegmentToPicoFeat (&(PositionOf (PointAt (Current))), ConvertSegmentToPicoFeat (&(PointAt (Current)->Point),
&(PositionOf (PointAt (Next))), FeatureSet); &(PointAt (Next)->Point), FeatureSet);
Current = Next; Current = Next;
Next = NextPointAfter (Current); Next = NextPointAfter (Current);
@ -284,14 +284,14 @@ void NormalizePicoX(FEATURE_SET FeatureSet) {
FEATURE Feature; FEATURE Feature;
FLOAT32 Origin = 0.0; FLOAT32 Origin = 0.0;
for (i = 0; i < NumFeaturesIn (FeatureSet); i++) { for (i = 0; i < FeatureSet->NumFeatures; i++) {
Feature = FeatureIn (FeatureSet, i); Feature = FeatureSet->Features[i];
Origin += ParamOf (Feature, PicoFeatX); Origin += Feature->Params[PicoFeatX];
} }
Origin /= NumFeaturesIn (FeatureSet); Origin /= FeatureSet->NumFeatures;
for (i = 0; i < NumFeaturesIn (FeatureSet); i++) { for (i = 0; i < FeatureSet->NumFeatures; i++) {
Feature = FeatureIn (FeatureSet, i); Feature = FeatureSet->Features[i];
ParamOf (Feature, PicoFeatX) -= Origin; Feature->Params[PicoFeatX] -= Origin;
} }
} /* NormalizePicoX */ } /* NormalizePicoX */

View File

@ -68,7 +68,7 @@ int AddConfigToClass(CLASS_TYPE Class) {
MaxNumProtos = Class->MaxNumProtos; MaxNumProtos = Class->MaxNumProtos;
if (NumConfigsIn (Class) >= Class->MaxNumConfigs) { if (Class->NumConfigs >= Class->MaxNumConfigs) {
/* add configs in CONFIG_INCREMENT chunks at a time */ /* add configs in CONFIG_INCREMENT chunks at a time */
NewNumConfigs = (((Class->MaxNumConfigs + CONFIG_INCREMENT) / NewNumConfigs = (((Class->MaxNumConfigs + CONFIG_INCREMENT) /
CONFIG_INCREMENT) * CONFIG_INCREMENT); CONFIG_INCREMENT) * CONFIG_INCREMENT);
@ -79,10 +79,10 @@ int AddConfigToClass(CLASS_TYPE Class) {
Class->MaxNumConfigs = NewNumConfigs; Class->MaxNumConfigs = NewNumConfigs;
} }
NewConfig = NumConfigsIn (Class); NewConfig = Class->NumConfigs;
NumConfigsIn (Class)++; Class->NumConfigs++;
Config = NewBitVector (MaxNumProtos); Config = NewBitVector (MaxNumProtos);
ConfigIn (Class, NewConfig) = Config; Class->Configurations[NewConfig] = Config;
zero_all_bits (Config, WordsInVectorOfSize (MaxNumProtos)); zero_all_bits (Config, WordsInVectorOfSize (MaxNumProtos));
return (NewConfig); return (NewConfig);
@ -102,7 +102,7 @@ int AddProtoToClass(CLASS_TYPE Class) {
int NewProto; int NewProto;
BIT_VECTOR Config; BIT_VECTOR Config;
if (NumProtosIn (Class) >= Class->MaxNumProtos) { if (Class->NumProtos >= Class->MaxNumProtos) {
/* add protos in PROTO_INCREMENT chunks at a time */ /* add protos in PROTO_INCREMENT chunks at a time */
NewNumProtos = (((Class->MaxNumProtos + PROTO_INCREMENT) / NewNumProtos = (((Class->MaxNumProtos + PROTO_INCREMENT) /
PROTO_INCREMENT) * PROTO_INCREMENT); PROTO_INCREMENT) * PROTO_INCREMENT);
@ -113,19 +113,18 @@ int AddProtoToClass(CLASS_TYPE Class) {
Class->MaxNumProtos = NewNumProtos; Class->MaxNumProtos = NewNumProtos;
for (i = 0; i < NumConfigsIn (Class); i++) { for (i = 0; i < Class->NumConfigs; i++) {
Config = ConfigIn (Class, i); Config = Class->Configurations[i];
ConfigIn (Class, i) = ExpandBitVector (Config, NewNumProtos); Class->Configurations[i] = ExpandBitVector (Config, NewNumProtos);
for (Bit = NumProtosIn (Class); Bit < NewNumProtos; Bit++) for (Bit = Class->NumProtos; Bit < NewNumProtos; Bit++)
reset_bit(Config, Bit); reset_bit(Config, Bit);
} }
} }
NewProto = NumProtosIn (Class); NewProto = Class->NumProtos++;
NumProtosIn (Class)++; if (Class->NumProtos > MAX_NUM_PROTOS) {
if (NumProtosIn(Class) > MAX_NUM_PROTOS) {
tprintf("Ouch! number of protos = %d, vs max of %d!", tprintf("Ouch! number of protos = %d, vs max of %d!",
NumProtosIn(Class), MAX_NUM_PROTOS); Class->NumProtos, MAX_NUM_PROTOS);
} }
return (NewProto); return (NewProto);
} }
@ -140,10 +139,10 @@ FLOAT32 ClassConfigLength(CLASS_TYPE Class, BIT_VECTOR Config) {
inT16 Pid; inT16 Pid;
FLOAT32 TotalLength = 0; FLOAT32 TotalLength = 0;
for (Pid = 0; Pid < NumProtosIn (Class); Pid++) { for (Pid = 0; Pid < Class->NumProtos; Pid++) {
if (test_bit (Config, Pid)) { if (test_bit (Config, Pid)) {
TotalLength += ProtoLength (ProtoIn (Class, Pid)); TotalLength += (ProtoIn (Class, Pid))->Length;
} }
} }
return (TotalLength); return (TotalLength);
@ -159,8 +158,8 @@ FLOAT32 ClassProtoLength(CLASS_TYPE Class) {
inT16 Pid; inT16 Pid;
FLOAT32 TotalLength = 0; FLOAT32 TotalLength = 0;
for (Pid = 0; Pid < NumProtosIn (Class); Pid++) { for (Pid = 0; Pid < Class->NumProtos; Pid++) {
TotalLength += ProtoLength (ProtoIn (Class, Pid)); TotalLength += (ProtoIn (Class, Pid))->Length;
} }
return (TotalLength); return (TotalLength);
} }
@ -172,13 +171,13 @@ FLOAT32 ClassProtoLength(CLASS_TYPE Class) {
* Copy the first proto into the second. * Copy the first proto into the second.
**********************************************************************/ **********************************************************************/
void CopyProto(PROTO Src, PROTO Dest) { void CopyProto(PROTO Src, PROTO Dest) {
ProtoX (Dest) = ProtoX (Src); Dest->X = Src->X;
ProtoY (Dest) = ProtoY (Src); Dest->Y = Src->Y;
ProtoLength (Dest) = ProtoLength (Src); Dest->Length = Src->Length;
ProtoAngle (Dest) = ProtoAngle (Src); Dest->Angle = Src->Angle;
CoefficientA (Dest) = CoefficientA (Src); Dest->A = Src->A;
CoefficientB (Dest) = CoefficientB (Src); Dest->B = Src->B;
CoefficientC (Dest) = CoefficientC (Src); Dest->C = Src->C;
} }
@ -224,8 +223,8 @@ void FreeClassFields(CLASS_TYPE Class) {
if (Class->MaxNumProtos > 0) if (Class->MaxNumProtos > 0)
memfree (Class->Prototypes); memfree (Class->Prototypes);
if (Class->MaxNumConfigs > 0) { if (Class->MaxNumConfigs > 0) {
for (i = 0; i < NumConfigsIn (Class); i++) for (i = 0; i < Class->NumConfigs; i++)
FreeBitVector (ConfigIn (Class, i)); FreeBitVector (Class->Configurations[i]);
memfree (Class->Configurations); memfree (Class->Configurations);
} }
} }
@ -277,7 +276,7 @@ CLASS_TYPE NewClass(int NumProtos, int NumConfigs) {
void PrintProtos(CLASS_TYPE Class) { void PrintProtos(CLASS_TYPE Class) {
inT16 Pid; inT16 Pid;
for (Pid = 0; Pid < NumProtosIn (Class); Pid++) { for (Pid = 0; Pid < Class->NumProtos; Pid++) {
cprintf ("Proto %d:\t", Pid); cprintf ("Proto %d:\t", Pid);
PrintProto (ProtoIn (Class, Pid)); PrintProto (ProtoIn (Class, Pid));
cprintf ("\t"); cprintf ("\t");
@ -343,18 +342,18 @@ void ReadConfigs(register FILE *File, CLASS_TYPE Class) {
int NumConfigs; int NumConfigs;
fscanf (File, "%d %d\n", &NumConfigs, &NumWords); fscanf (File, "%d %d\n", &NumConfigs, &NumWords);
NumConfigsIn (Class) = NumConfigs; Class->NumConfigs = NumConfigs;
Class->MaxNumConfigs = NumConfigs; Class->MaxNumConfigs = NumConfigs;
Class->Configurations = Class->Configurations =
(CONFIGS) Emalloc (sizeof (BIT_VECTOR) * NumConfigs); (CONFIGS) Emalloc (sizeof (BIT_VECTOR) * NumConfigs);
NumWords = WordsInVectorOfSize (NumProtosIn (Class)); NumWords = WordsInVectorOfSize (Class->NumProtos);
for (Cid = 0; Cid < NumConfigs; Cid++) { for (Cid = 0; Cid < NumConfigs; Cid++) {
ThisConfig = NewBitVector (NumProtosIn (Class)); ThisConfig = NewBitVector (Class->NumProtos);
for (Wid = 0; Wid < NumWords; Wid++) for (Wid = 0; Wid < NumWords; Wid++)
fscanf (File, "%x", &ThisConfig[Wid]); fscanf (File, "%x", &ThisConfig[Wid]);
ConfigIn (Class, Cid) = ThisConfig; Class->Configurations[Cid] = ThisConfig;
} }
} }
@ -371,19 +370,19 @@ void ReadProtos(register FILE *File, CLASS_TYPE Class) {
int NumProtos; int NumProtos;
fscanf (File, "%d\n", &NumProtos); fscanf (File, "%d\n", &NumProtos);
NumProtosIn (Class) = NumProtos; Class->NumProtos = NumProtos;
Class->MaxNumProtos = NumProtos; Class->MaxNumProtos = NumProtos;
Class->Prototypes = (PROTO) Emalloc (sizeof (PROTO_STRUCT) * NumProtos); Class->Prototypes = (PROTO) Emalloc (sizeof (PROTO_STRUCT) * NumProtos);
for (Pid = 0; Pid < NumProtos; Pid++) { for (Pid = 0; Pid < NumProtos; Pid++) {
Proto = ProtoIn (Class, Pid); Proto = ProtoIn (Class, Pid);
fscanf (File, "%f %f %f %f %f %f %f\n", fscanf (File, "%f %f %f %f %f %f %f\n",
&ProtoX (Proto), &Proto->X,
&ProtoY (Proto), &Proto->Y,
&ProtoLength (Proto), &Proto->Length,
&ProtoAngle (Proto), &Proto->Angle,
&CoefficientA (Proto), &Proto->A,
&CoefficientB (Proto), &CoefficientC (Proto)); &Proto->B, &Proto->C);
} }
} }
@ -404,8 +403,8 @@ int SplitProto(CLASS_TYPE Class, int OldPid) {
NewPid = AddProtoToClass (Class); NewPid = AddProtoToClass (Class);
for (i = 0; i < NumConfigsIn (Class); i++) { for (i = 0; i < Class->NumConfigs; i++) {
Config = ConfigIn (Class, i); Config = Class->Configurations[i];
if (test_bit (Config, OldPid)) if (test_bit (Config, OldPid))
SET_BIT(Config, NewPid); SET_BIT(Config, NewPid);
} }
@ -423,14 +422,14 @@ void WriteOldConfigFile(FILE *File, CLASS_TYPE Class) {
int Cid, Pid; int Cid, Pid;
BIT_VECTOR Config; BIT_VECTOR Config;
fprintf (File, "%d %d\n", NumConfigsIn (Class), NumProtosIn (Class)); fprintf (File, "%d %d\n", Class->NumConfigs, Class->NumProtos);
for (Cid = 0; Cid < NumConfigsIn (Class); Cid++) { for (Cid = 0; Cid < Class->NumConfigs; Cid++) {
fprintf (File, "1 "); fprintf (File, "1 ");
Config = ConfigIn (Class, Cid); Config = Class->Configurations[Cid];
for (Pid = 0; Pid < NumProtosIn (Class); Pid++) { for (Pid = 0; Pid < Class->NumProtos; Pid++) {
if (test_bit (Config, Pid)) if (test_bit (Config, Pid))
fprintf (File, "1"); fprintf (File, "1");
else else
@ -460,13 +459,13 @@ void WriteOldProtoFile(FILE *File, CLASS_TYPE Class) {
fprintf (File, "linear non-essential -0.500000 0.500000\n"); fprintf (File, "linear non-essential -0.500000 0.500000\n");
fprintf (File, "linear non-essential -0.500000 0.500000\n"); fprintf (File, "linear non-essential -0.500000 0.500000\n");
for (Pid = 0; Pid < NumProtosIn (Class); Pid++) { for (Pid = 0; Pid < Class->NumProtos; Pid++) {
Proto = ProtoIn (Class, Pid); Proto = ProtoIn (Class, Pid);
fprintf (File, "significant elliptical 1\n"); fprintf (File, "significant elliptical 1\n");
fprintf (File, " %9.6f %9.6f %9.6f %9.6f %9.6f %9.6f\n", fprintf (File, " %9.6f %9.6f %9.6f %9.6f %9.6f %9.6f\n",
ProtoX (Proto), ProtoY (Proto), Proto->X, Proto->Y,
ProtoLength (Proto), ProtoAngle (Proto), 0.0, 0.0); Proto->Length, Proto->Angle, 0.0, 0.0);
fprintf (File, " %9.6f %9.6f %9.6f %9.6f %9.6f %9.6f\n", fprintf (File, " %9.6f %9.6f %9.6f %9.6f %9.6f %9.6f\n",
0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001); 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001);
} }

View File

@ -115,109 +115,6 @@ extern CLASS_STRUCT TrainingData[];
#define ProtoIn(Class,Pid) \ #define ProtoIn(Class,Pid) \
(& (Class)->Prototypes [Pid]) (& (Class)->Prototypes [Pid])
/**********************************************************************
* ConfigIn
*
* Choose the selected prototype configuration in this class record.
* Return it as type 'BIT_VECTOR'.
**********************************************************************/
#define ConfigIn(Class,Cid) \
((Class)->Configurations [Cid])
/**********************************************************************
* NumProtosIn
*
* Return the number of prototypes in this class. The 'Class' argument
* is of type 'CLASS_TYPE'.
**********************************************************************/
#define NumProtosIn(Class) \
((Class)->NumProtos)
/**********************************************************************
* NumConfigsIn
*
* Return the number of configurations in this class. The 'Class' argument
* is of type 'CLASS_TYPE'.
**********************************************************************/
#define NumConfigsIn(Class) \
((Class)->NumConfigs)
/**********************************************************************
* CoefficientA
*
* Return the first parameter of the prototype structure. This is the
* A coefficient in the line representation of "Ax + By + C = 0". The
* 'Proto' argument is of type 'PROTO'.
**********************************************************************/
#define CoefficientA(Proto) \
((Proto)->A)
/**********************************************************************
* CoefficientB
*
* Return the second parameter of the prototype structure. This is the
* B coefficient in the line representation of "Ax + By + C = 0". The
* 'Proto' argument is of type 'PROTO'.
**********************************************************************/
#define CoefficientB(Proto) \
((Proto)->B)
/**********************************************************************
* CoefficientC
*
* Return the third parameter of the prototype structure. This is the
* C coefficient in the line representation of "Ax + By + C = 0". The
* 'Proto' argument is of type 'PROTO'.
**********************************************************************/
#define CoefficientC(Proto) \
((Proto)->C)
/**********************************************************************
* ProtoAngle
*
* Return the angle parameter of the prototype structure. The
* 'Proto' argument is of type 'PROTO'.
**********************************************************************/
#define ProtoAngle(Proto) \
((Proto)->Angle)
/**********************************************************************
* ProtoX
*
* Return the X parameter of the prototype structure. The 'Proto'
* argument is of type 'PROTO'.
**********************************************************************/
#define ProtoX(Proto) \
((Proto)->X)
/**********************************************************************
* ProtoY
*
* Return the angle parameter of the prototype structure. The 'Proto'
* argument is of type 'PROTO'.
**********************************************************************/
#define ProtoY(Proto) \
((Proto)->Y)
/**********************************************************************
* ProtoLength
*
* Return the length parameter of the prototype structure. The
* 'Proto' argument is of type 'PROTO'.
**********************************************************************/
#define ProtoLength(Proto) \
((Proto)->Length)
/********************************************************************** /**********************************************************************
* PrintProto * PrintProto
* *
@ -227,10 +124,10 @@ extern CLASS_STRUCT TrainingData[];
#define PrintProto(Proto) \ #define PrintProto(Proto) \
(cprintf ("X=%4.2f, Y=%4.2f, Angle=%4.2f", \ (cprintf ("X=%4.2f, Y=%4.2f, Angle=%4.2f", \
ProtoX (Proto), \ Proto->X, \
ProtoY (Proto), \ Proto->Y, \
ProtoLength (Proto), \ Proto->Length, \
ProtoAngle (Proto))) \ Proto->Angle)) \
/********************************************************************** /**********************************************************************
@ -242,9 +139,9 @@ extern CLASS_STRUCT TrainingData[];
#define PrintProtoLine(Proto) \ #define PrintProtoLine(Proto) \
(cprintf ("A=%4.2f, B=%4.2f, C=%4.2f", \ (cprintf ("A=%4.2f, B=%4.2f, C=%4.2f", \
CoefficientA (Proto), \ Proto->A, \
CoefficientB (Proto), \ Proto->B, \
CoefficientC (Proto))) \ Proto->C)) \
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
F u n c t i o n s F u n c t i o n s

View File

@ -24,6 +24,63 @@
/**---------------------------------------------------------------------------- /**----------------------------------------------------------------------------
Public Code Public Code
----------------------------------------------------------------------------**/ ----------------------------------------------------------------------------**/
void InitMatrix(MATRIX_2D *M) {
M->a = 1;
M->b = 0;
M->c = 0;
M->d = 1;
M->tx = 0;
M->ty = 0;
}
void CopyMatrix(MATRIX_2D *A, MATRIX_2D *B) {
B->a = A->a;
B->b = A->b;
B->c = A->c;
B->d = A->d;
B->tx = A->tx;
B->ty = A->ty;
}
void TranslateMatrix(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y) {
M->tx += M->a * X + M->c * Y;
M->ty += M->b * X + M->d * Y;
}
void ScaleMatrix(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y) {
M->a *= X;
M->b *= X;
M->c *= Y;
M->d *= Y;
}
void MirrorMatrixInX(MATRIX_2D *M) {ScaleMatrix(M, -1, 1);}
void MirrorMatrixInY(MATRIX_2D *M) {ScaleMatrix(M, 1, -1);}
void MirrorMatrixInXY(MATRIX_2D *M) {ScaleMatrix(M, -1, -1);}
FLOAT32 MapX(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y) {
return M->a * (X) + (M)->c * (Y) + (M)->tx;
}
FLOAT32 MapY(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y) {
return M->b * X + M->d * Y + M->ty;
}
void MapPoint(MATRIX_2D *M, FPOINT &A, FPOINT &B) {
B.x = MapX (M, A.x, A.y);
B.y = MapY (M, A.x, A.y);
}
FLOAT32 MapDx(MATRIX_2D *M, FLOAT32 DX, FLOAT32 DY) {
return M->a * DX + M->c * DY;
}
FLOAT32 MapDy(MATRIX_2D *M, FLOAT32 DX, FLOAT32 DY) {
return M->b * DX + M->d * DY;
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void RotateMatrix(MATRIX_2D_PTR Matrix, FLOAT32 Angle) { void RotateMatrix(MATRIX_2D_PTR Matrix, FLOAT32 Angle) {
/* /*

View File

@ -31,39 +31,30 @@ typedef struct
MATRIX_2D, *MATRIX_2D_PTR; MATRIX_2D, *MATRIX_2D_PTR;
/**----------------------------------------------------------------------------
Macros
----------------------------------------------------------------------------**/
/* macros for initializing transform matrices */
#define InitMatrix(M) ((M)->a = 1, (M)->b = 0, \
(M)->c = 0, (M)->d = 1, \
(M)->tx = 0, (M)->ty = 0 )
#define CopyMatrix(A,B) ((B)->a = (A)->a, (B)->b = (A)->b, \
(B)->c = (A)->c, (B)->d = (A)->d, \
(B)->tx = (A)->tx, (B)->ty = (A)->ty)
/* matrix scaling, translation, rotation, mirroring, etc.*/
#define TranslateMatrix(M,X,Y) ((M)->tx += (M)->a * (X) + (M)->c * (Y), \
(M)->ty += (M)->b * (X) + (M)->d * (Y) )
#define ScaleMatrix(M,X,Y) ((M)->a *= (X), (M)->b *= (X), \
(M)->c *= (Y), (M)->d *= (Y))
#define MirrorMatrixInX(M) (ScaleMatrix((M),-1,1))
#define MirrorMatrixInY(M) (ScaleMatrix((M),1,-1))
#define MirrorMatrixInXY(M) (ScaleMatrix((M),-1,-1))
/* using a matrix to map points*/
#define MapX(M,X,Y) ((M)->a * (X) + (M)->c * (Y) + (M)->tx)
#define MapY(M,X,Y) ((M)->b * (X) + (M)->d * (Y) + (M)->ty)
#define MapPoint(M,A,B) (Xof(B) = MapX (M, Xof(A), Yof(A)), \
Yof(B) = MapY (M, Xof(A), Yof(A)))
#define MapDx(M,DX,DY) ((M)->a * (DX) + (M)->c * (DY))
#define MapDy(M,DX,DY) ((M)->b * (DX) + (M)->d * (DY))
/**---------------------------------------------------------------------------- /**----------------------------------------------------------------------------
Public Function Prototypes Public Function Prototypes
----------------------------------------------------------------------------**/ ----------------------------------------------------------------------------**/
void RotateMatrix(MATRIX_2D_PTR Matrix, FLOAT32 Angle);
void InitMatrix(MATRIX_2D *M);
void CopyMatrix(MATRIX_2D *A, MATRIX_2D *B);
/* matrix scaling, translation, rotation, mirroring, etc.*/
void TranslateMatrix(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y);
void ScaleMatrix(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y);
void MirrorMatrixInX(MATRIX_2D *M);
void MirrorMatrixInY(MATRIX_2D *M);
void MirrorMatrixInXY(MATRIX_2D *M);
/* using a matrix to map points*/
FLOAT32 MapX(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y);
FLOAT32 MapY(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y);
void MapPoint(MATRIX_2D *M, FPOINT &A, FPOINT &B);
FLOAT32 MapDx(MATRIX_2D *M, FLOAT32 DX, FLOAT32 DY);
FLOAT32 MapDy(MATRIX_2D M, FLOAT32 DX, FLOAT32 DY);
void RotateMatrix(MATRIX_2D_PTR Matrix, FLOAT32 Angle);
#endif #endif

View File

@ -446,7 +446,7 @@ void ReadTrainingSamples (
} }
CharDesc = ReadCharDescription (File); CharDesc = ReadCharDescription (File);
Type = ShortNameToFeatureType(PROGRAM_FEATURE_TYPE); Type = ShortNameToFeatureType(PROGRAM_FEATURE_TYPE);
FeatureSamples = FeaturesOfType(CharDesc, Type); FeatureSamples = CharDesc->FeatureSets[Type];
for (int feature = 0; feature < FeatureSamples->NumFeatures; ++feature) { for (int feature = 0; feature < FeatureSamples->NumFeatures; ++feature) {
FEATURE f = FeatureSamples->Features[feature]; FEATURE f = FeatureSamples->Features[feature];
for (int dim =0; dim < f->Type->NumParams; ++dim) for (int dim =0; dim < f->Type->NumParams; ++dim)
@ -454,9 +454,9 @@ void ReadTrainingSamples (
} }
CharSample->List = push (CharSample->List, FeatureSamples); CharSample->List = push (CharSample->List, FeatureSamples);
CharSample->SampleCount++; CharSample->SampleCount++;
for (i = 0; i < NumFeatureSetsIn (CharDesc); i++) for (i = 0; i < CharDesc->NumFeatureSets; i++)
if (Type != i) if (Type != i)
FreeFeatureSet (FeaturesOfType (CharDesc, i)); FreeFeatureSet(CharDesc->FeatureSets[i]);
free (CharDesc); free (CharDesc);
} }
} // ReadTrainingSamples } // ReadTrainingSamples
@ -574,7 +574,7 @@ void WriteTrainingSamples (
{ {
File = Efopen (Filename, "w"); File = Efopen (Filename, "w");
WriteOldParamDesc WriteOldParamDesc
(File, DefinitionOf (ShortNameToFeatureType (PROGRAM_FEATURE_TYPE))); (File, FeatureDefs.FeatureDesc[ShortNameToFeatureType (PROGRAM_FEATURE_TYPE)]);
} }
else else
{ {
@ -768,7 +768,7 @@ CLUSTERER *SetUpForClustering(
FEATURE_DESC FeatureDesc = NULL; FEATURE_DESC FeatureDesc = NULL;
// PARAM_DESC* ParamDesc; // PARAM_DESC* ParamDesc;
FeatureDesc = DefinitionOf(ShortNameToFeatureType(PROGRAM_FEATURE_TYPE)); FeatureDesc = FeatureDefs.FeatureDesc[ShortNameToFeatureType(PROGRAM_FEATURE_TYPE)];
N = FeatureDesc->NumParams; N = FeatureDesc->NumParams;
//ParamDesc = ConvertToPARAMDESC(FeatureDesc->ParamDesc, N); //ParamDesc = ConvertToPARAMDESC(FeatureDesc->ParamDesc, N);
Clusterer = MakeClusterer(N,FeatureDesc->ParamDesc); Clusterer = MakeClusterer(N,FeatureDesc->ParamDesc);

View File

@ -95,24 +95,24 @@ FLOAT32 CompareProtos (
FLOAT32 Angle, Length; FLOAT32 Angle, Length;
/* if p1 and p2 are not close in length, don't let them match */ /* if p1 and p2 are not close in length, don't let them match */
Length = fabs (ProtoLength (p1) - ProtoLength (p2)); Length = fabs (p1->Length - p2->Length);
if (Length > MAX_LENGTH_MISMATCH) if (Length > MAX_LENGTH_MISMATCH)
return (0.0); return (0.0);
/* create a dummy pico-feature to be used for comparisons */ /* create a dummy pico-feature to be used for comparisons */
Feature = NewFeature (&PicoFeatDesc); Feature = NewFeature (&PicoFeatDesc);
ParamOf (Feature, PicoFeatDir) = ProtoAngle (p1); Feature->Params[PicoFeatDir] = p1->Angle;
/* convert angle to radians */ /* convert angle to radians */
Angle = ProtoAngle (p1) * 2.0 * PI; Angle = p1->Angle * 2.0 * PI;
/* find distance from center of p1 to 1/2 picofeat from end */ /* find distance from center of p1 to 1/2 picofeat from end */
Length = ProtoLength (p1) / 2.0 - GetPicoFeatureLength () / 2.0; Length = p1->Length / 2.0 - GetPicoFeatureLength () / 2.0;
if (Length < 0) Length = 0; if (Length < 0) Length = 0;
/* set the dummy pico-feature at one end of p1 and match it to p2 */ /* set the dummy pico-feature at one end of p1 and match it to p2 */
ParamOf (Feature, PicoFeatX) = ProtoX (p1) + cos (Angle) * Length; Feature->Params[PicoFeatX] = p1->X + cos (Angle) * Length;
ParamOf (Feature, PicoFeatY) = ProtoY (p1) + sin (Angle) * Length; Feature->Params[PicoFeatY] = p1->Y + sin (Angle) * Length;
if (DummyFastMatch (Feature, p2)) if (DummyFastMatch (Feature, p2))
{ {
Evidence = SubfeatureEvidence (Feature, p2); Evidence = SubfeatureEvidence (Feature, p2);
@ -126,8 +126,8 @@ FLOAT32 CompareProtos (
} }
/* set the dummy pico-feature at the other end of p1 and match it to p2 */ /* set the dummy pico-feature at the other end of p1 and match it to p2 */
ParamOf (Feature, PicoFeatX) = ProtoX (p1) - cos (Angle) * Length; Feature->Params[PicoFeatX] = p1->X - cos (Angle) * Length;
ParamOf (Feature, PicoFeatY) = ProtoY (p1) - sin (Angle) * Length; Feature->Params[PicoFeatY] = p1->Y - sin (Angle) * Length;
if (DummyFastMatch (Feature, p2)) if (DummyFastMatch (Feature, p2))
{ {
Evidence = SubfeatureEvidence (Feature, p2); Evidence = SubfeatureEvidence (Feature, p2);
@ -174,10 +174,10 @@ void ComputeMergedProto (
w1 /= TotalWeight; w1 /= TotalWeight;
w2 /= TotalWeight; w2 /= TotalWeight;
ProtoX (MergedProto) = ProtoX (p1) * w1 + ProtoX (p2) * w2; MergedProto->X = p1->X * w1 + p2->X * w2;
ProtoY (MergedProto) = ProtoY (p1) * w1 + ProtoY (p2) * w2; MergedProto->Y = p1->Y * w1 + p2->Y * w2;
ProtoLength (MergedProto) = ProtoLength (p1) * w1 + ProtoLength (p2) * w2; MergedProto->Length = p1->Length * w1 + p2->Length * w2;
ProtoAngle (MergedProto) = ProtoAngle (p1) * w1 + ProtoAngle (p2) * w2; MergedProto->Angle = p1->Angle * w1 + p2->Angle * w2;
FillABC (MergedProto); FillABC (MergedProto);
} /* ComputeMergedProto */ } /* ComputeMergedProto */
@ -216,7 +216,7 @@ int FindClosestExistingProto (
BestProto = NO_PROTO; BestProto = NO_PROTO;
BestMatch = WORST_MATCH_ALLOWED; BestMatch = WORST_MATCH_ALLOWED;
for (Pid = 0; Pid < NumProtosIn (Class); Pid++) for (Pid = 0; Pid < Class->NumProtos; Pid++)
{ {
Proto = ProtoIn (Class, Pid); Proto = ProtoIn (Class, Pid);
ComputeMergedProto (Proto, &NewProto, ComputeMergedProto (Proto, &NewProto,
@ -252,10 +252,10 @@ void MakeNewFromOld (
*/ */
{ {
ProtoX (New) = CenterX (Old->Mean); New->X = CenterX (Old->Mean);
ProtoY (New) = CenterY (Old->Mean); New->Y = CenterY (Old->Mean);
ProtoLength (New) = LengthOf (Old->Mean); New->Length = LengthOf (Old->Mean);
ProtoAngle (New) = OrientationOf (Old->Mean); New->Angle = OrientationOf (Old->Mean);
FillABC (New); FillABC (New);
} /* MakeNewFromOld */ } /* MakeNewFromOld */
@ -286,14 +286,14 @@ FLOAT32 SubfeatureEvidence (
float Distance; float Distance;
float Dangle; float Dangle;
Dangle = ProtoAngle (Proto) - ParamOf(Feature, PicoFeatDir); Dangle = Proto->Angle - Feature->Params[PicoFeatDir];
if (Dangle < -0.5) Dangle += 1.0; if (Dangle < -0.5) Dangle += 1.0;
if (Dangle > 0.5) Dangle -= 1.0; if (Dangle > 0.5) Dangle -= 1.0;
Dangle *= AngleMatchScale; Dangle *= AngleMatchScale;
Distance = CoefficientA (Proto) * ParamOf(Feature, PicoFeatX) + Distance = Proto->A * Feature->Params[PicoFeatX] +
CoefficientB (Proto) * ParamOf(Feature, PicoFeatY) + Proto->B * Feature->Params[PicoFeatY] +
CoefficientC (Proto); Proto->C;
return (EvidenceOf (Distance * Distance + Dangle * Dangle)); return (EvidenceOf (Distance * Distance + Dangle * Dangle));
} }
@ -366,7 +366,7 @@ BOOL8 DummyFastMatch (
FLOAT32 AngleError; FLOAT32 AngleError;
MaxAngleError = AnglePad / 360.0; MaxAngleError = AnglePad / 360.0;
AngleError = fabs (ProtoAngle (Proto) - ParamOf (Feature, PicoFeatDir)); AngleError = fabs (Proto->Angle - Feature->Params[PicoFeatDir]);
if (AngleError > 0.5) if (AngleError > 0.5)
AngleError = 1.0 - AngleError; AngleError = 1.0 - AngleError;
@ -379,8 +379,8 @@ BOOL8 DummyFastMatch (
&BoundingBox); &BoundingBox);
return (PointInside (&BoundingBox, return (PointInside (&BoundingBox,
ParamOf (Feature, PicoFeatX), Feature->Params[PicoFeatX],
ParamOf (Feature, PicoFeatY))); Feature->Params[PicoFeatY]));
} /* DummyFastMatch */ } /* DummyFastMatch */
@ -411,18 +411,18 @@ void ComputePaddedBoundingBox (
FLOAT32 Pad, Length, Angle; FLOAT32 Pad, Length, Angle;
FLOAT32 CosOfAngle, SinOfAngle; FLOAT32 CosOfAngle, SinOfAngle;
Length = ProtoLength (Proto) / 2.0 + TangentPad; Length = Proto->Length / 2.0 + TangentPad;
Angle = ProtoAngle (Proto) * 2.0 * PI; Angle = Proto->Angle * 2.0 * PI;
CosOfAngle = fabs (cos (Angle)); CosOfAngle = fabs (cos (Angle));
SinOfAngle = fabs (sin (Angle)); SinOfAngle = fabs (sin (Angle));
Pad = MAX (CosOfAngle * Length, SinOfAngle * OrthogonalPad); Pad = MAX (CosOfAngle * Length, SinOfAngle * OrthogonalPad);
BoundingBox->MinX = ProtoX (Proto) - Pad; BoundingBox->MinX = Proto->X - Pad;
BoundingBox->MaxX = ProtoX (Proto) + Pad; BoundingBox->MaxX = Proto->Y + Pad;
Pad = MAX (SinOfAngle * Length, CosOfAngle * OrthogonalPad); Pad = MAX (SinOfAngle * Length, CosOfAngle * OrthogonalPad);
BoundingBox->MinY = ProtoY (Proto) - Pad; BoundingBox->MinY = Proto->Y - Pad;
BoundingBox->MaxY = ProtoY (Proto) + Pad; BoundingBox->MaxY = Proto->Y + Pad;
} /* ComputePaddedBoundingBox */ } /* ComputePaddedBoundingBox */

View File

@ -351,7 +351,7 @@ int main (int argc, char **argv) {
ProtoIn (MergeClass->Class, Pid)); ProtoIn (MergeClass->Class, Pid));
MergeClass->NumMerged[Pid] ++; MergeClass->NumMerged[Pid] ++;
} }
Config2 = ConfigIn (MergeClass->Class, Cid); Config2 = MergeClass->Class->Configurations[Cid];
AddProtoToConfig (Pid, Config2); AddProtoToConfig (Pid, Config2);
} }
FreeProtoList (&ProtoList); FreeProtoList (&ProtoList);
@ -582,7 +582,7 @@ LIST ReadTrainingSamples (
} }
CharDesc = ReadCharDescription (File); CharDesc = ReadCharDescription (File);
Type = ShortNameToFeatureType(PROGRAM_FEATURE_TYPE); Type = ShortNameToFeatureType(PROGRAM_FEATURE_TYPE);
FeatureSamples = FeaturesOfType(CharDesc, Type); FeatureSamples = CharDesc->FeatureSets[Type];
for (int feature = 0; feature < FeatureSamples->NumFeatures; ++feature) { for (int feature = 0; feature < FeatureSamples->NumFeatures; ++feature) {
FEATURE f = FeatureSamples->Features[feature]; FEATURE f = FeatureSamples->Features[feature];
for (int dim =0; dim < f->Type->NumParams; ++dim) for (int dim =0; dim < f->Type->NumParams; ++dim)
@ -592,9 +592,9 @@ LIST ReadTrainingSamples (
} }
CharSample->List = push (CharSample->List, FeatureSamples); CharSample->List = push (CharSample->List, FeatureSamples);
CharSample->SampleCount++; CharSample->SampleCount++;
for (i = 0; i < NumFeatureSetsIn (CharDesc); i++) for (i = 0; i < CharDesc->NumFeatureSets; i++)
if (Type != i) if (Type != i)
FreeFeatureSet (FeaturesOfType (CharDesc, i)); FreeFeatureSet(CharDesc->FeatureSets[i]);
free (CharDesc); free (CharDesc);
} }
return (TrainingSamples); return (TrainingSamples);
@ -745,7 +745,7 @@ void WriteTrainingSamples (
{ {
File = Efopen (Filename, "w"); File = Efopen (Filename, "w");
WriteOldParamDesc WriteOldParamDesc
(File, DefinitionOf (ShortNameToFeatureType (PROGRAM_FEATURE_TYPE))); (File, FeatureDefs.FeatureDesc[ShortNameToFeatureType (PROGRAM_FEATURE_TYPE)]);
} }
else else
{ {
@ -896,15 +896,15 @@ void WriteProtos(
PROTO Proto; PROTO Proto;
fprintf(File, "%s\n", MergeClass->Label); fprintf(File, "%s\n", MergeClass->Label);
fprintf(File, "%d\n", NumProtosIn(MergeClass->Class)); fprintf(File, "%d\n", MergeClass->Class->NumProtos);
for(i=0; i < NumProtosIn(MergeClass->Class); i++) for(i=0; i < (MergeClass->Class)->NumProtos; i++)
{ {
Proto = ProtoIn(MergeClass->Class,i); Proto = ProtoIn(MergeClass->Class,i);
fprintf(File, "\t%8.4f %8.4f %8.4f %8.4f ", ProtoX(Proto), ProtoY(Proto), fprintf(File, "\t%8.4f %8.4f %8.4f %8.4f ", Proto->X, Proto->Y,
ProtoLength(Proto), ProtoAngle(Proto)); Proto->Length, Proto->Angle);
Values[0] = ProtoX(Proto); Values[0] = Proto->X;
Values[1] = ProtoY(Proto); Values[1] = Proto->Y;
Values[2] = ProtoAngle(Proto); Values[2] = Proto->Angle;
Normalize(Values); Normalize(Values);
fprintf(File, "%8.4f %8.4f %8.4f\n", Values[0], Values[1], Values[2]); fprintf(File, "%8.4f %8.4f %8.4f\n", Values[0], Values[1], Values[2]);
} }
@ -918,11 +918,11 @@ void WriteConfigs(
BIT_VECTOR Config; BIT_VECTOR Config;
int i, j, WordsPerConfig; int i, j, WordsPerConfig;
WordsPerConfig = WordsInVectorOfSize(NumProtosIn(Class)); WordsPerConfig = WordsInVectorOfSize(Class->NumProtos);
fprintf(File, "%d %d\n", NumConfigsIn(Class),WordsPerConfig); fprintf(File, "%d %d\n", Class->NumConfigs, WordsPerConfig);
for(i=0; i < NumConfigsIn(Class); i++) for(i=0; i < Class->NumConfigs; i++)
{ {
Config = ConfigIn(Class,i); Config = Class->Configurations[i];
for(j=0; j < WordsPerConfig; j++) for(j=0; j < WordsPerConfig; j++)
fprintf(File, "%08x ", Config[j]); fprintf(File, "%08x ", Config[j]);
fprintf(File, "\n"); fprintf(File, "\n");
@ -1055,7 +1055,7 @@ CLUSTERER *SetUpForClustering(
FEATURE_DESC FeatureDesc = NULL; FEATURE_DESC FeatureDesc = NULL;
// PARAM_DESC* ParamDesc; // PARAM_DESC* ParamDesc;
FeatureDesc = DefinitionOf(ShortNameToFeatureType(PROGRAM_FEATURE_TYPE)); FeatureDesc = FeatureDefs.FeatureDesc[ShortNameToFeatureType(PROGRAM_FEATURE_TYPE)];
N = FeatureDesc->NumParams; N = FeatureDesc->NumParams;
// ParamDesc = ConvertToPARAMDESC(FeatureDesc->ParamDesc, N); // ParamDesc = ConvertToPARAMDESC(FeatureDesc->ParamDesc, N);
Clusterer = MakeClusterer(N,FeatureDesc->ParamDesc); Clusterer = MakeClusterer(N,FeatureDesc->ParamDesc);
@ -1285,40 +1285,40 @@ void SetUpForFloat2Int(
MergeClass = (MERGE_CLASS) first_node (LabeledClassList); MergeClass = (MERGE_CLASS) first_node (LabeledClassList);
Class = &TrainingData[unicharset_mftraining.unichar_to_id( Class = &TrainingData[unicharset_mftraining.unichar_to_id(
MergeClass->Label)]; MergeClass->Label)];
NumProtos = NumProtosIn(MergeClass->Class); NumProtos = (MergeClass->Class)->NumProtos;
NumConfigs = NumConfigsIn(MergeClass->Class); NumConfigs = MergeClass->Class->NumConfigs;
NumProtosIn(Class) = NumProtos; Class->NumProtos = NumProtos;
Class->MaxNumProtos = NumProtos; Class->MaxNumProtos = NumProtos;
Class->Prototypes = (PROTO) Emalloc (sizeof(PROTO_STRUCT) * NumProtos); Class->Prototypes = (PROTO) Emalloc (sizeof(PROTO_STRUCT) * NumProtos);
for(i=0; i < NumProtos; i++) for(i=0; i < NumProtos; i++)
{ {
NewProto = ProtoIn(Class, i); NewProto = ProtoIn(Class, i);
OldProto = ProtoIn(MergeClass->Class, i); OldProto = ProtoIn(MergeClass->Class, i);
Values[0] = ProtoX(OldProto); Values[0] = OldProto->X;
Values[1] = ProtoY(OldProto); Values[1] = OldProto->Y;
Values[2] = ProtoAngle(OldProto); Values[2] = OldProto->Angle;
Normalize(Values); Normalize(Values);
ProtoX(NewProto) = ProtoX(OldProto); NewProto->X = OldProto->X;
ProtoY(NewProto) = ProtoY(OldProto); NewProto->Y = OldProto->Y;
ProtoLength(NewProto) = ProtoLength(OldProto); NewProto->Length = OldProto->Length;
ProtoAngle(NewProto) = ProtoAngle(OldProto); NewProto->Angle = OldProto->Angle;
CoefficientA(NewProto) = Values[0]; NewProto->A = Values[0];
CoefficientB(NewProto) = Values[1]; NewProto->B = Values[1];
CoefficientC(NewProto) = Values[2]; NewProto->C = Values[2];
} }
NumConfigsIn(Class) = NumConfigs; Class->NumConfigs = NumConfigs;
Class->MaxNumConfigs = NumConfigs; Class->MaxNumConfigs = NumConfigs;
Class->Configurations = (BIT_VECTOR*) Emalloc (sizeof(BIT_VECTOR) * NumConfigs); Class->Configurations = (BIT_VECTOR*) Emalloc (sizeof(BIT_VECTOR) * NumConfigs);
NumWords = WordsInVectorOfSize(NumProtos); NumWords = WordsInVectorOfSize(NumProtos);
for(i=0; i < NumConfigs; i++) for(i=0; i < NumConfigs; i++)
{ {
NewConfig = NewBitVector(NumProtos); NewConfig = NewBitVector(NumProtos);
OldConfig = ConfigIn(MergeClass->Class, i); OldConfig = MergeClass->Class->Configurations[i];
for(j=0; j < NumWords; j++) for(j=0; j < NumWords; j++)
NewConfig[j] = OldConfig[j]; NewConfig[j] = OldConfig[j];
ConfigIn(Class, i) = NewConfig; Class->Configurations[i] = NewConfig;
} }
} }
} // SetUpForFloat2Int } // SetUpForFloat2Int
@ -1327,15 +1327,15 @@ void SetUpForFloat2Int(
void WritePFFMTable(INT_TEMPLATES Templates, const char* filename) { void WritePFFMTable(INT_TEMPLATES Templates, const char* filename) {
FILE* fp = Efopen(filename, "wb"); FILE* fp = Efopen(filename, "wb");
/* then write out each class */ /* then write out each class */
for (int i = 0; i < NumClassesIn (Templates); i++) { for (int i = 0; i < Templates->NumClasses; i++) {
int MaxLength = 0; int MaxLength = 0;
INT_CLASS Class = ClassForIndex (Templates, i); INT_CLASS Class = Templates->Class[i];
for (int ConfigId = 0; ConfigId < NumIntConfigsIn (Class); ConfigId++) { for (int ConfigId = 0; ConfigId < Class->NumConfigs; ConfigId++) {
if (LengthForConfigId (Class, ConfigId) > MaxLength) if (Class->ConfigLengths[ConfigId] > MaxLength)
MaxLength = LengthForConfigId (Class, ConfigId); MaxLength = Class->ConfigLengths[ConfigId];
} }
fprintf(fp, "%s %d\n", unicharset_mftraining.id_to_unichar( fprintf(fp, "%s %d\n", unicharset_mftraining.id_to_unichar(
ClassIdForIndex(Templates, i)), MaxLength); Templates->ClassIdFor[i]), MaxLength);
} }
fclose(fp); fclose(fp);
} // WritePFFMTable } // WritePFFMTable