📄 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 <malloc.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"/* JHC: Moved here from hre.h to avoid confusion */#define GESTURE "GESTURE" /* gestures only */#define MATHSET "MATHSET" /* %^*()_+={}<>,/. */#define MONEYSET "MONEYSET" /* $, maybe cent, pound, and yen */#define WHITESPACE "WHITESPACE" /* gaps are recognized as space */#define KANJI_JIS1 "KANJI_JIS1" /* the JIS1 kanji only */#define KANJI_JIS1_PLUS "KANJI_JIS1_PLUS" /* JIS1 plus some JIS2 */#define KANJI_JIS2 "KANJI_JIS2" /* the JIS1 + JIS2 kanji */#define HIRIGANA "HIRIGANA" /* the hirigana */#define KATAKANA "KATAKANA" /* the katakana */#define UPPERCASE "UPPERCASE" /* upper case alphabetics, no digits */#define LOWERCASE "LOWERCASE" /* lower case alphabetics, no digits */#define DIGITS "DIGITS" /* digits 0-9 only */#define PUNCTUATION "PUNCTUATION" /* \!-;'"?()&., */#define NONALPHABETIC "NONALPHABETIC" /* all nonalphabetics, no digits */#define ASCII "ASCII" /* the ASCII character set */#define ISO_LATIN12 "ISO_LATIN12" /* The ISO Latin 12 characters */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];#define bcopy(s1,s2,n) memcpy(s2,s1,n)#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 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 intfile_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 intread_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) { 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) { goto unallocate; /*Boy would I like exceptions! */ } /*Allocate array for points. */ if ((pts = make_pen_point_array(npts)) == NULL) { goto unallocate; } /*Read in points. */ for (j = 0; j < npts; j++) { int x, y; if (fscanf(fd, "%d %d", &x, &y) != 2) { delete_pen_point_array(pts); 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); 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 intread_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 boolisa_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 intli_recognizer_load(recognizer r, char *dir, char *filename){ FILE *fd; //int ftype; 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 intli_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"; return (NULL);}static intli_recognizer_save_dictionary(recognizer rec, char *directory, char *name, wordset dict){ /*This operation isn't supported by the LI recognizer. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -