⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 li_recognizer.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 *  li_recognizer.c
 *
 *	Copyright 2000 Compaq Computer Corporation.
 *	Copying or modifying this code for any purpose is permitted,
 *	provided that this copyright notice is preserved in its entirety
 *	in all copies or modifications.
 *	COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR
 *	IMPLIED, AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR
 *
 *
 *  Adapted from cmu_recognizer.c by Jay Kistler.
 *  
 *  Where is the CMU copyright???? Gotta track it down - Jim Gettys
 *
 *  Credit to Dean Rubine, Jim Kempf, and Ari Rapkin.
 */


#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#ifndef ELX
#include <stdlib.h>
#endif
#include <math.h>
#include <locale.h>
#include <hre_internal.h>
#include <setjmp.h>
#include "util.h"
#include "matrix.h"
#include "sc.h"
#include "li_recognizer.h"
#include "li_recognizer_internal.h"


int lidebug = 0;

/*LI Magic Number.*/

#define LI_MAGIC 0xACCBADDD

#define CHECK_LI_MAGIC(_a) \
  ((_a) != NULL && ((li_recognizer*)(_a))->li_magic == LI_MAGIC)


static void lialg_initialize(rClassifier *);
static int lialg_read_classifier_digest(rClassifier *);
static int lialg_canonicalize_examples(rClassifier *);
static char *lialg_recognize_stroke(rClassifier *, point_list *);


char* li_err_msg = NULL;
char _zdebug_flag[128];

#ifndef __ECOS
// This is standard - defined in <stdlib.h>
#define bcopy(s1,s2,n) memcpy(s2,s1,n)
#endif

#if 0 /* was #ifdef mips*/
char *strdup(char* from) {
   char* to;
   int len = strlen(from) + 1;

   /*   to = (char *) safe_malloc( len * sizeof(char) );*/
   to = allocate(len, char);
   memcpy(to, from, len);
   return to;
}
#endif


/*Freeing classifier*/

static void
free_rClassifier(rClassifier* rc);

/*
 * Point List Support
*/

static point_list*
add_example(point_list* l,int npts,pen_point* pts)
{
    pen_point* lpts = make_pen_point_array(npts);
    /*    point_list* p = (point_list*)safe_malloc(sizeof(point_list));*/
    point_list *p = allocate(1, point_list);

    p->npts = npts;
    p->pts = lpts;
    p->next = l;       /*Order doesn't matter, so we stick on end.*/

    /*Copy points.*/

    bcopy(pts,lpts,npts * sizeof(pen_point));

    return(p);
}
    

static void
delete_examples(point_list* l)
{
    point_list* p;

    for( ; l != NULL; l = p ) {
	p = l->next;
	free(l->pts);
	free(l);
    }
}

/*
 * Local functions
 */

/*
 * recognize_internal-Form Vector, use Classifier to classify, return char.
 */

static char*
  recognize_internal(rClassifier* rec,pen_stroke* str,int* rconf)
{
    char *res = NULL;
    point_list *stroke = NULL;

    stroke = add_example(NULL, str->ps_npts, str->ps_pts);
    if (stroke == NULL) return(NULL);

    res = lialg_recognize_stroke(rec, stroke);

    delete_examples(stroke);
    return(res);
}

/*
 * file_path-Construct pathname, check for proper extension.
 */

static int
  file_path(char* dir,char* filename,char* pathname)
{
    char* dot;
    
    /*Check for proper extension on file name.*/
    
    dot = strrchr(filename,'.');
    
    if( dot == NULL ) {
	return(-1);
    }

    /*Determine whether a gesture or character classifier.*/

    if( strcmp(dot,LI_CLASSIFIER_EXTENSION) != 0 ) {
	return(-1);
    }

    /*Concatenate directory and filename into pathname.*/
    
    strcpy(pathname,dir);
    strcat(pathname,"/");
    strcat(pathname,filename);
    
    return(0);
}

/*read_classifier_points-Read points so classifier can be extended.*/

static int 
read_classifier_points(FILE* fd,int nclss,point_list** ex,char** cnames)
{
    int i,j,k;
    char buf[BUFSIZ];
    int nex = 0;
    char* names[MAXSCLASSES];
    point_list* examples[MAXSCLASSES];
    pen_point* pts;
    int npts;

    /*Initialize*/

    for( i = 0; i < MAXSCLASSES; i++ ) {
	names[i] = NULL;
	examples[i] = NULL;
    }

    /*Go thru classes.*/

/* ari */
/* fprintf(stderr, "Classes: [ "); */

    for( k = 0; k < nclss; k++ ) {

	/*Read class name and number of examples.*/
	
	if( fscanf(fd,"%d %s",&nex,buf) != 2 ) {
            printf("%s *FAILED* - line: %d\n", __FUNCTION__, __LINE__);
	    goto unallocate;
	}
	
	/*Save class name*/
	
	names[k] = strdup(buf);
/* ari */
/* fprintf(stderr, "%s ", buf); */

	/*Read examples.*/
	
	for( i = 0; i < nex; i++ ) {
	    
	    /*Read number of points.*/
	    
	    if( fscanf(fd,"%d",&npts) != 1 ) {
                printf("%s *FAILED* - line: %d\n", __FUNCTION__, __LINE__);
		goto unallocate; /*Boy would I like exceptions!*/
	    }
	    
	    /*Allocate array for points.*/
	    
	    if( (pts = make_pen_point_array(npts)) == NULL ) {
                printf("%s *FAILED* - line: %d\n", __FUNCTION__, __LINE__);
		goto unallocate;
	    }
	    
	    /*Read in points.*/
	    
	    for( j = 0; j < npts; j++ ) {
		int x,y;
                int jj;
		if( fscanf(fd,"%d %d",&x,&y) != 2 ) {
		    delete_pen_point_array(pts);
                    printf("%s *FAILED* - line: %d\n", __FUNCTION__, __LINE__);
                    printf("class = %d/%d/%s, ex = %d/%d, pt: %d/%d\n", 
                                k, nclss, names[k], i, nex, j, npts);
                    for (jj = 0;  jj < j;  jj++) {
                        printf("pts[%d] = %d/%d\n", jj, pts[jj].x, pts[jj].y);
                    }
		    goto unallocate;
		}
		pts[j].x = x;
		pts[j].y = y;
	    }
	    
	    /*Add example*/
	    
	    if( (examples[k] = add_example(examples[k],npts,pts)) == NULL ) {
		delete_pen_point_array(pts);
                printf("%s *FAILED* - line: %d\n", __FUNCTION__, __LINE__);
		goto unallocate;
	    }
	    
	    delete_pen_point_array(pts);
	    
	  }
      }

/* ari -- end of list of classes */
/* fprintf(stderr, "]\n"); */

    /*Transfer to recognizer.*/

    bcopy(examples,ex,sizeof(examples));
    bcopy(names,cnames,sizeof(names));

    return(0);

    /*Error. Deallocate memory and return.*/

  unallocate:

    for( ; k >= 0; k-- ) {
	delete_examples(examples[k]);
	free(names[k]);
    }

    error("Error in reading example points from classifier file");
    return(-1);
}

/*read_classifier-Read a classifier file.*/

static int read_classifier(FILE* fd,rClassifier* rc)
{
    sClassifier sc;
    
    li_err_msg = NULL;

    /*Read in classifier file.*/
    
    if( (sc = sRead(fd)) == NULL ) {
	return(-1);
    }
    
    /*Read in the example points, so classifier can be extended.*/

    if( read_classifier_points(fd,sc->nclasses,rc->ex,rc->cnames) != 0 ) {
	sFreeClassifier(sc);
	return(-1);
    }

    /*Transfer sClassifier to the rClassifier*/

    rc->sc = sc;
    
    return(0);
}

/*
 * Extension Functions
*/

/* getClasses and clearState are by Ari */

static int
recognizer_getClasses (recognizer r, char ***list, int *nc)
{
    int i, nclasses;
    li_recognizer* rec;
    sClassifier sc;
    char **ret;

    rec = (li_recognizer*)r->recognizer_specific;

    /*Check for LI recognizer.*/

    if( !CHECK_LI_MAGIC(rec) ) {
	li_err_msg = "Not a LI recognizer";
	return(-1);
    }
    
    sc = rec->li_rc.sc;
    *nc = nclasses = sc->nclasses;
    /*    ret = (char **) safe_malloc (nclasses * sizeof(char*));*/
    ret = allocate(nclasses, char*);

    for (i = 0; i < nclasses; i++) {
      ret[i] = rec->li_rc.cnames[i];   /* only the 1st char of the cname */
    }
    *list = ret;
    return 0;
}

static int
recognizer_clearState (recognizer r)
{
  /*This operation isn't supported by the LI recognizer.*/

  li_err_msg = "Clearing state is not supported by the LI recognizer";

  return(-1);
}

static bool isa_li(recognizer r)
{ return(CHECK_LI_MAGIC(r)); }

static int
recognizer_train(recognizer r,rc* rec_xt,u_int nstrokes,
		    pen_stroke* strokes,rec_element* re,
		    bool replace_p)
{
  /*This operation isn't supported by the LI recognizer.*/

  li_err_msg = "Training is not supported by the LI recognizer";

  return(-1);
}

int
li_recognizer_get_example (recognizer	r,
			   int		class, 
			   int		instance,
			   char		**name, 
			   pen_point	**points,
			   int		*npts)
{
    li_recognizer   *rec = (li_recognizer*)r->recognizer_specific;
    sClassifier	    sc = rec->li_rc.sc;
    point_list	    *pl;
    
    if( !CHECK_LI_MAGIC(rec) ) {
	li_err_msg = "Not a LI recognizer";
	return(-1);
    }
    if (class > sc->nclasses)
	return -1;
    pl = rec->li_rc.canonex[class];
    while (instance && pl)
    {
	pl = pl->next;
	instance--;
    }
    if (!pl)
	return -1;
    *name = rec->li_rc.cnames[class];
    *points = pl->pts;
    *npts = pl->npts;
    return 0;
}

/*
 * API Functions
 */


/*li_recognizer_load-Load a classifier file.*/

static int li_recognizer_load(recognizer r,char* dir,char* filename)
{ 
    FILE *fd;
    char* pathname;
    li_recognizer* rec;
    rClassifier* rc;
    
    rec = (li_recognizer*)r->recognizer_specific;

    /*Make sure recognizer's OK*/

    if( !CHECK_LI_MAGIC(rec) ) {
	li_err_msg = "Not a LI recognizer";
	return(-1);
    }

    rc = &(rec->li_rc);

    /*Check parameters.*/

    if( filename == NULL ) {
	li_err_msg = "Invalid parameters";
	return(-1);
    }

    /*We let the directory be null.*/

    if( dir == NULL || (int)strlen(dir) <= 0 ) {
	dir = ".";
    }

    /*Make full pathname and check filename*/

    /* pathname = (char*)safe_malloc(strlen(dir) + strlen(filename) + 2)); */

    pathname = allocate(strlen(dir) + strlen(filename) + 2, char);
    if( file_path(dir,filename,pathname) == -1 ) {
	free(pathname);
	li_err_msg = "Not a LI recognizer classifier file";
	return(-1);
    }

    /* Try to short-circuit the full classifier-file processing. */
    rc->file_name = pathname;
    if (lialg_read_classifier_digest(rc) == 0)
	return(0);
    rc->file_name = NULL;

    /*Open the file*/

    if( (fd = fopen(pathname,"r")) == NULL ) {
	free(pathname);
	li_err_msg = "Can't open classifier file";
/* ari */
	/* fprintf(stderr, "Trying to open %s.\n", pathname); */
	return(-1);

    }

    /*If rClassifier is OK, then delete it first.*/

    if( rc->file_name != NULL ) {
      free_rClassifier(rc);
    }

    /*Read classifier.*/
    
    if( read_classifier(fd,rc) < 0 ) {
	free(pathname);
	return(-1);
    }

    /*Close file.*/

    fclose(fd);

    /*Add classifier name.*/

    rc->file_name = pathname;

    /* Canonicalize examples. */
    if (lialg_canonicalize_examples(rc) != 0) {
	free(pathname);
	rc->file_name = NULL;
	return(-1);
    }

    return(0);
}

/*li_recognizer_save-Save a classifier file.*/

static int li_recognizer_save(recognizer r,char* dir,char* filename)
{ 
  /*This operation isn't supported by the LI recognizer.*/

  li_err_msg = "Saving is not supported by the LI recognizer";

  return(-1);
}

static wordset

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -