/******************************************************************************
 **	Filename:    features.c
 **	Purpose:     Generic definition of a feature.
 **	Author:      Dan Johnson
 **	History:     Mon May 21 10:49:04 1990, DSJ, Created.
 **
 **	(c) Copyright Hewlett-Packard Company, 1988.
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 ** http://www.apache.org/licenses/LICENSE-2.0
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 ******************************************************************************/
/**----------------------------------------------------------------------------
          Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "ocrfeatures.h"
#include "emalloc.h"
#include "callcpp.h"
#include "danerror.h"
#include "freelist.h"
#include "scanutils.h"

/**----------------------------------------------------------------------------
              Public Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
BOOL8 AddFeature(FEATURE_SET FeatureSet, FEATURE Feature) {
/*
 **	Parameters:
 **		FeatureSet	set of features to add Feature to
 **		Feature		feature to be added to FeatureSet
 **	Globals: none
 **	Operation: Add a feature to a feature set.  If the feature set is
 **		already full, FALSE is returned to indicate that the
 **		feature could not be added to the set; otherwise, TRUE is
 **		returned.
 **	Return: TRUE if feature added to set, FALSE if set is already full.
 **	Exceptions: none
 **	History: Tue May 22 17:22:23 1990, DSJ, Created.
 */
  if (NumFeaturesIn (FeatureSet) >= MaxNumFeaturesIn (FeatureSet)) {
    FreeFeature(Feature);
    return (FALSE);
  }

  FeatureIn (FeatureSet, NumFeaturesIn (FeatureSet)) = Feature;
  NumFeaturesIn (FeatureSet)++;
  return (TRUE);

}                                /* AddFeature */


/*---------------------------------------------------------------------------*/
void DefaultInitFXVars() {
/*
 **	Parameters: none
 **	Globals: none
 **	Operation: This routine can be used by any feature extractor which
 **		does not use adjustable controls.
 **		It does nothing.
 **	Return: none
 **	Exceptions: none
 **	History: Wed May 23 16:37:45 1990, DSJ, Created.
 */
}                                /* DefaultInitFXVars */


/*---------------------------------------------------------------------------*/
void FreeFeature(FEATURE Feature) {
/*
 **	Parameters:
 **		Feature		feature to be deallocated.
 **	Globals: none
 **	Operation: Release the memory consumed by the specified feature.
 **	Return: none
 **	Exceptions: none
 **	History: Mon May 21 13:33:27 1990, DSJ, Created.
 */
  if (Feature) {
    free_struct (Feature, sizeof (FEATURE_STRUCT)
      + sizeof (FLOAT32) * (NumParamsIn (Feature) - 1),
      "sizeof(FEATURE_STRUCT)+sizeof(FLOAT32)*(NumParamsIn(Feature)-1)");
  }

}                                /* FreeFeature */


/*---------------------------------------------------------------------------*/
void FreeFeatureSet(FEATURE_SET FeatureSet) {
/*
 **	Parameters:
 **		FeatureSet	set of features to be freed
 **	Globals: none
 **	Operation: Release the memory consumed by the specified feature
 **		set.  This routine also frees the memory consumed by the
 **		features contained in the set.
 **	Return: none
 **	Exceptions: none
 **	History: Mon May 21 13:59:46 1990, DSJ, Created.
 */
  int i;

  if (FeatureSet) {
    for (i = 0; i < NumFeaturesIn (FeatureSet); i++)
      FreeFeature (FeatureIn (FeatureSet, i));
    memfree(FeatureSet);
  }
}                                /* FreeFeatureSet */


/*---------------------------------------------------------------------------*/
FEATURE NewFeature(FEATURE_DESC FeatureDesc) {
/*
 **	Parameters:
 **		FeatureDesc	description of feature to be created.
 **	Globals: none
 **	Operation: Allocate and return a new feature of the specified
 **		type.
 **	Return: New feature.
 **	Exceptions: none
 **	History: Mon May 21 14:06:42 1990, DSJ, Created.
 */
  FEATURE Feature;

  Feature = (FEATURE) alloc_struct (sizeof (FEATURE_STRUCT) +
    (FeatureDesc->NumParams - 1) *
    sizeof (FLOAT32),
    "sizeof(FEATURE_STRUCT)+sizeof(FLOAT32)*(NumParamsIn(Feature)-1)");
  TypeOf (Feature) = FeatureDesc;
  return (Feature);

}                                /* NewFeature */


/*---------------------------------------------------------------------------*/
FEATURE_SET NewFeatureSet(int NumFeatures) {
/*
 **	Parameters:
 **		NumFeatures	maximum # of features to be put in feature set
 **	Globals: none
 **	Operation: Allocate and return a new feature set large enough to
 **		hold the specified number of features.
 **	Return: New feature set.
 **	Exceptions: none
 **	History: Mon May 21 14:22:40 1990, DSJ, Created.
 */
  FEATURE_SET FeatureSet;

  FeatureSet = (FEATURE_SET) Emalloc (sizeof (FEATURE_SET_STRUCT) +
    (NumFeatures - 1) * sizeof (FEATURE));
  MaxNumFeaturesIn (FeatureSet) = NumFeatures;
  NumFeaturesIn (FeatureSet) = 0;
  return (FeatureSet);

}                                /* NewFeatureSet */


/*---------------------------------------------------------------------------*/
FEATURE ReadFeature(FILE *File, FEATURE_DESC FeatureDesc) {
/*
 **	Parameters:
 **		File		open text file to read feature from
 **		FeatureDesc	specifies type of feature to read from File
 **	Globals: none
 **	Operation: Create a new feature of the specified type and read in
 **		the value of its parameters from File.  The extra penalty
 **		for the feature is also computed by calling the appropriate
 **		function for the specified feature type.  The correct text
 **		representation for a feature is a list of N floats where
 **		N is the number of parameters in the feature.
 **	Return: New feature read from File.
 **	Exceptions: ILLEGAL_FEATURE_PARAM if text file doesn't match expected format
 **	History: Wed May 23 08:53:16 1990, DSJ, Created.
 */
  FEATURE Feature;
  int i;

  Feature = NewFeature (FeatureDesc);
  for (i = 0; i < NumParamsIn (Feature); i++) {
    if (fscanf (File, "%f", &(ParamOf (Feature, i))) != 1)
      DoError (ILLEGAL_FEATURE_PARAM, "Illegal feature parameter spec");
  }
  return (Feature);

}                                /* ReadFeature */


/*---------------------------------------------------------------------------*/
FEATURE_SET ReadFeatureSet(FILE *File, FEATURE_DESC FeatureDesc) {
/*
 **	Parameters:
 **		File		open text file to read new feature set from
 **		FeatureDesc	specifies type of feature to read from File
 **	Globals: none
 **	Operation: Create a new feature set of the specified type and read in
 **		the features from File.  The correct text representation
 **		for a feature set is an integer which specifies the number (N)
 **		of features in a set followed by a list of N feature
 **		descriptions.
 **	Return: New feature set read from File.
 **	Exceptions: none
 **	History: Wed May 23 09:17:31 1990, DSJ, Created.
 */
  FEATURE_SET FeatureSet;
  int NumFeatures;
  int i;

  if (fscanf (File, "%d", &NumFeatures) != 1 || NumFeatures < 0)
    DoError (ILLEGAL_NUM_FEATURES, "Illegal number of features in set");

  FeatureSet = NewFeatureSet (NumFeatures);
  for (i = 0; i < NumFeatures; i++)
    AddFeature (FeatureSet, ReadFeature (File, FeatureDesc));

  return (FeatureSet);

}                                /* ReadFeatureSet */


/*---------------------------------------------------------------------------*/
void WriteFeature(FILE *File, FEATURE Feature) {
/*
 **	Parameters:
 **		File		open text file to write Feature to
 **		Feature		feature to write out to File
 **	Globals: none
 **	Operation: Write a textual representation of Feature to File.
 **		This representation is simply a list of the N parameters
 **		of the feature, terminated with a newline.  It is assumed
 **		that the ExtraPenalty field can be reconstructed from the
 **		parameters of the feature.  It is also assumed that the
 **		feature type information is specified or assumed elsewhere.
 **	Return: none
 **	Exceptions: none
 **	History: Wed May 23 09:28:18 1990, DSJ, Created.
 */
  int i;

  for (i = 0; i < NumParamsIn (Feature); i++)
    fprintf (File, " %12g", ParamOf (Feature, i));
  fprintf (File, "\n");

}                                /* WriteFeature */


/*---------------------------------------------------------------------------*/
void WriteFeatureSet(FILE *File, FEATURE_SET FeatureSet) {
/*
 **	Parameters:
 **		File		open text file to write FeatureSet to
 **		FeatureSet	feature set to write to File
 **	Globals: none
 **	Operation: Write a textual representation of FeatureSet to File.
 **		This representation is an integer specifying the number of
 **		features in the set, followed by a newline, followed by
 **		text representations for each feature in the set.
 **	Return: none
 **	Exceptions: none
 **	History: Wed May 23 10:06:03 1990, DSJ, Created.
 */
  int i;

  if (FeatureSet) {
    fprintf (File, "%d\n", NumFeaturesIn (FeatureSet));
    for (i = 0; i < NumFeaturesIn (FeatureSet); i++)
      WriteFeature (File, FeatureIn (FeatureSet, i));
  }
}                                /* WriteFeatureSet */


/*---------------------------------------------------------------------------*/
void WriteOldParamDesc(FILE *File, FEATURE_DESC FeatureDesc) {
/*
 **	Parameters:
 **		File		open text file to write FeatureDesc to
 **		FeatureDesc	feature descriptor to write to File
 **	Globals: none
 **	Operation: Write a textual representation of FeatureDesc to File
 **		in the old format (i.e. the format used by the clusterer).
 **		This format is:
 **			Number of Params
 **			Description of Param 1
 **			...
 **	Return: none
 **	Exceptions: none
 **	History: Fri May 25 15:27:18 1990, DSJ, Created.
 */
  int i;

  fprintf (File, "%d\n", FeatureDesc->NumParams);
  for (i = 0; i < FeatureDesc->NumParams; i++) {
    if (FeatureDesc->ParamDesc[i].Circular)
      fprintf (File, "circular ");
    else
      fprintf (File, "linear   ");

    if (FeatureDesc->ParamDesc[i].NonEssential)
      fprintf (File, "non-essential  ");
    else
      fprintf (File, "essential      ");

    fprintf (File, "%f  %f\n",
      FeatureDesc->ParamDesc[i].Min, FeatureDesc->ParamDesc[i].Max);
  }
}                                /* WriteOldParamDesc */
