📄 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 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 + -