📄 li_recognizer.c
字号:
/* * 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 voidfree_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 voiddelete_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 intrecognizer_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 intrecognizer_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 intrecognizer_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);}intli_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 wordsetli_recognizer_load_dictionary(recognizer rec,char* directory,char* name){ /*This operation isn't supported by the LI recognizer.*/ li_err_msg = "Dictionaries are not supported by the LI recognizer";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -