/* Copyright (C) 1999-2002 Ricardo Ueda Karpischek This is free software; you can redistribute it and/or modify it under the terms of the version 2 of the GNU General Public License as published by the Free Software Foundation. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this software; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* cml.c: ClaraML dump and recover */ #include #include #include #include "common.h" #include "gui.h" /* current line on session dump */ int DLINE; /* line size */ int DLS = 80; /* Returns true if s is a non-empty string. */ int nonempty(char *s) { if (s == NULL) return(0); else for (; (*s==' ') || (*s=='\r') || (*s=='\t') || (*s=='\n'); ++s); if (*s == 0) return(0); else return(1); } /* Convert structure field to asc. */ void toasc(FILE *F,char *name,int type,int n,void *f) { int i,r,d; static char *s = NULL; static int max; char sep; /* silently ignore NULL strings */ if ((type == TSTR) && (f == NULL)) return; /* alloc initial buffer */ if (s == NULL) s = c_realloc(NULL,max=4096,NULL); /* dump field name */ if ((d=snprintf(s,max,"%s",name)) < 0) { fatal(BO,"buffer overflow at toasc\n"); } /* STR to CHAR */ if (type == TSTR) { type = TCHAR; n = strlen((char *)f); } /* empty array */ if ((n==0) && (type != TNULL)) { r = snprintf(s+d,max-d,"="); if (r < 0) { fatal(BO,"buffer overflow at toasc\n"); } d += r; } /* dump array */ else for (sep='=', i=0; i max-128) { if (F == NULL) totext("%s",s); else fprintf(F,"%s",s); s[d=0] = 0; } if (type == TCHAR) r = snprintf(s+d,max-d,"%c%x",sep,*(((unsigned char *)f)+i)); else if (type == TSHORT) r = snprintf(s+d,max-d,"%c%d",sep,*(((short *)f)+i)); else if (type == TFLOAT) r = snprintf(s+d,max-d,"%c%f",sep,*(((float *)f)+i)); else if (type == TINT) r = snprintf(s+d,max-d,"%c%d",sep,*(((int *)f)+i)); else { r = 0; db("unknown type %d at toasc",type); } if (r < 0) { fatal(BO,"buffer overflow at toasc\n"); } d += r; sep = ','; } /* record delimiter */ if ((snprintf(s+d,max-d,"\n")) < 0) { fatal(BO,"buffer overflow at toasc\n"); } /* send to output */ if (F == NULL) totext("%s",s); else zfwrite(s,strlen(s),1,F); } /* Read one line from dump. Returns the address of the buffer where the line was put, or NULL if the input is exhausted. */ char *recover_line(FILE *F) { static int psz=0; static char *s; int i,t,end; /* alloc initial buffer */ if (s == NULL) s = c_realloc(NULL,psz=512,NULL); /* reading loop */ for (t=0, end=0; end==0; ) { if (F != NULL) { if ((fgets(s+t,psz-t-1,F) == NULL) && (feof(F))) end = 1; else t += strlen(s+t); } else { int nl; if (text[topt] == 0) end = 1; for (nl = 0; (t+10) && (s[t]==0) && (s[t-1]=='\n')) { ++DLINE; /* remove comment (if any) */ for (i=0; i= psz-2) { s = c_realloc(s,psz+=512,NULL); } } } /* input exhausted */ return(NULL); } /* This is a complex service. It reads the input F searching for a field name and a list of atoms, like "f=1" or "cl=122,479". The type of the atoms is informed through the "type" parameter. If type==TNULL, searches for a single field name, like "a" or "blue". Returns 0 if end-of-file is detected before reading all that stuff. Returns -1 if the field name informed throug the "name" parameter did not match the name read from input. If the field name matched, reads all atoms and store them on an internal buffer. If the parameter "size" is strictly positive, then returns -1 if the number of atoms read is not equal to "size". If the number of atoms read is equal to "size", or if "size" is 0 or strictly negative, returns the number of atoms and exports the array of atoms to another buffer. This another buffer is that pointed to by f, if "size" is nonzero. Otherwise, this buffer will be allocated and its address will return in *f. If "size" is strictly negative, assumes that -size is the maximum number of atoms to be read. */ int fromasc(FILE *F,char *name,int type,int size,void *f) { static char *s = NULL; static char *b = NULL; static int bs=0; char *e,*g; int n,t,ts; long r; double d; /* type size */ if (type == TCHAR) ts = sizeof(char); else if (type == TSHORT) ts = sizeof(short); else if (type == TFLOAT) ts = sizeof(float); else if (type == TINT) ts = sizeof(int); else if (type == TSTR) ts = sizeof(char); else if (type == TNULL) ts = 0; else { ts = -1; db("unknown type %d at fromasc",type); } /* read one non-empty input line or fail */ if ((s == NULL) && ((s = recover_line(F)) == NULL)) { return(0); } /* field name does not match */ t = strlen(name); if ((strncmp(s,name,t) != 0) || ((type != TNULL) && (s[t] != '='))) { /* if string, initialize to NULL */ if ((size == 0) && (type == TSTR)) *((void **)f) = NULL; return(-1); } /* no array to be read */ if (type == TNULL) { n = 0; e = s = NULL; } else e = s+t+1; /* read array */ for (n=0; (e != NULL); ) { /* just to avoid a compilation warning */ d = r = 0; if ((type == TCHAR) || (type == TSTR)) r = strtol(e,&g,16); else if (type == TSHORT) r = strtol(e,&g,10); else if (type == TFLOAT) d = strtod(e,&g); else if (type == TINT) r = strtol(e,&g,10); /* no other element found */ if (e == g) { s = NULL; e = NULL; } /* found element */ else { /* add it to b */ if (f != NULL) { /* enlarge memory buffer */ if (bs < (n+1)*ts) b = c_realloc(b,bs+=512,NULL); /* exceeded size */ if (((size > 0) && (n >= size)) || ((size < 0) && (n >= -size))) { return(0); } /* add */ else if ((type == TCHAR) || (type == TSTR)) *(((char *)b)+n) = r; else if (type == TSHORT) *(((short *)b)+n) = r; else if (type == TFLOAT) *(((float *)b)+n) = d; else if (type == TINT) *(((int *)b)+n) = r; } /* count and advance */ ++n; e = g + 1; } } /* invalid size */ if ((size > 0) && (n != size)) { return(0); } /* If f is not NULL, then store the array on *f. If size is 0, then alloc memory and make *f point to it. */ if (((n > 0) || (type == TSTR)) && (f != NULL)) { /* alloc memory */ if (size == 0) { if (type == TSTR) { *((void **)f) = c_realloc(NULL,(n+1)*ts,NULL); memcpy(*((void **)f),b,n*ts); *(((char *) *((void **)f)) + n) = 0; } else { *((void **)f) = c_realloc(NULL,n*ts,NULL); memcpy(*((void **)f),b,n*ts); } } /* copy to the pre-allocated buffer */ else memcpy(f,b,n*ts); } /* return array size */ return(n); } /* Session Dumper. */ int dump_session(char *f,int reset) { static int i,st; int bms; static FILE *F; static int pio; if (reset) { if ((F = zfopen(f,"w",&pio)) == NULL) return(0); else { st = 0; return(1); } } /* finished */ if (st == 7) { fprintf(F,"%s","\n"); zfclose(F,pio); sess_changed = 0; return(0); } /* one quantum more */ switch (st) { /* magic */ case 0: toasc(F,"",TNULL,0,NULL); fprintf(F,"\n"); st = 1; i = 0; break; /* unstructured variables */ case 1: toasc(F," 0) toasc(F,"limits",TINT,8*zones,limits); toasc(F,"curr_mc",TINT,1,&curr_mc); toasc(F,"symbols",TINT,1,&symbols); toasc(F,"doubts",TINT,1,&doubts); toasc(F,"runs",TINT,1,&runs); toasc(F,"ocr_time",TINT,1,&ocr_time); toasc(F,"ocr_r",TINT,1,&ocr_r); toasc(F,"words",TINT,1,&words); toasc(F,"classes",TINT,1,&classes); toasc(F,">\n",TNULL,0,NULL); st = 2; i = 0; break; /* closures */ case 2: if (i > topcl) { st = 3; i = 0; } else { int topsup; if ((batch_mode == 0) && ((i % DPROG) == 0)) { snprintf(mba,MMB,"now saving closure %d/%d",i,topcl); show_hint(0,mba); } toasc(F,"=0; ++topsup); toasc(F,"sup",TINT,topsup,cl[i].sup); toasc(F,">\n",TNULL,0,NULL); ++i; } break; /* symbols */ case 3: if (i > tops) { st = 4; i = 0; } else { trdesc *t; if ((batch_mode == 0) && ((i % DPROG) == 0)) { snprintf(mba,MMB,"now saving symbol %d/%d",i,tops); show_hint(0,mba); } toasc(F,"\n",TNULL,0,NULL); /* transliterations */ for (t=mc[i].tr; t != NULL; t=t->nt) { vdesc *v; toasc(F,"pr)); toasc(F,"n",TINT,1,&(t->n)); toasc(F,"f",TINT,1,&(t->f)); toasc(F,"a",TCHAR,1,&(t->a)); toasc(F,"t",TCHAR,strlen(t->t),t->t); toasc(F,">\n",TNULL,0,NULL); /* votes */ for (v=t->v; v!=NULL; v=(vdesc *)v->nv) { toasc(F,"orig)); toasc(F,"act",TINT,1,&(v->act)); toasc(F,"q",TCHAR,1,&(v->q)); toasc(F,">\n",TNULL,0,NULL); } } /* prepare next symbol */ ++i; } break; /* links */ case 4: if (i > toplk) { st = 5; i = 0; } else { if ((batch_mode == 0) && ((i % DPROG) == 0)) { snprintf(mba,MMB,"now saving link %d/%d",i,toplk); show_hint(0,mba); } toasc(F,"\n",TNULL,0,NULL); ++i; } break; /* lines */ case 5: if (i > topln) { st = 6; i = 0; } else { if ((batch_mode == 0) && ((i % DPROG) == 0)) { snprintf(mba,MMB,"now saving line %d/%d",i,topln); show_hint(0,mba); } toasc(F,"\n",TNULL,0,NULL); ++i; } break; /* words */ case 6: if (i > topw) { st = 7; i = 0; } else { if ((batch_mode == 0) && ((i % DPROG) == 0)) { snprintf(mba,MMB,"now saving word %d/%d",i,topw); show_hint(0,mba); } toasc(F,"\n",TNULL,0,NULL); ++i; } break; } /* unfinished */ return(1); } /* Acts Dumper. */ int dump_acts(char *f,int reset) { static int i,st,pio; static FILE *F; if (reset) { if (f == NULL) { F = NULL; topt = -1; } else { if ((F = zfopen(f,"w",&pio)) == NULL) return(0); } st = 0; i = 0; return(1); } /* successfully finished */ if (st == 3) { toasc(F,"\n",TNULL,0,NULL); if (F != NULL) zfclose(F,pio); hist_changed = 0; return(0); } switch (st) { /* magic */ case 0: toasc(F,"",TNULL,0,NULL); toasc(F,"\n",TNULL,0,NULL); st = 1; i = 0; /* unstructured variables */ case 1: st = 2; i = 0; break; /* Dump all acts if output is a file, or only the topmost act if the output is the array text. */ case 2: if (i > topa) { st = 3; i = 0; } else { if (F==NULL) i = topa; if ((batch_mode == 0) && ((F != NULL) && ((i % DPROG) == 0))) { snprintf(mba,MMB,"now saving act %d/%d",i,topa); show_hint(0,mba); } /* preamble */ toasc(F,"\n",TNULL,0,NULL); /* prepare next act */ ++i; } } /* unfinished */ return(1); } /* Dump patterns to disk. */ int dump_patterns(char *f,int reset) { static FILE *F; pdesc *s; static int i,st,pio; if (reset) { if ((F = zfopen(f,"w",&pio)) == NULL) return(0); i = 0; st = 0; return(1); } /* successfully finished */ if (st == 4) { fprintf(F,"%s","\n"); zfclose(F,pio); font_changed = 0; return(0); } switch (st) { /* magic */ case 0: toasc(F,"",TNULL,0,NULL); fprintf(F,"\n"); st = 1; i = 0; break; /* unstructured variables */ case 1: toasc(F,"\n",TNULL,0,NULL); st = 2; i = 0; break; /* patterns */ case 2: if (i > topp) { st = 3; i = 0; } else { if ((batch_mode == 0) && ((i % DPROG) == 0)) { snprintf(mba,MMB,"now saving pattern %d/%d",i,topp); show_hint(0,mba); } s = pattern + i; toasc(F,"dt)); */ toasc(F,"id",TINT,1,&(s->id)); toasc(F,"bw",TSHORT,1,&(s->bw)); toasc(F,"bh",TSHORT,1,&(s->bh)); toasc(F,"bb",TSHORT,1,&(s->bb)); toasc(F,"bp",TSHORT,1,&(s->bp)); toasc(F,"sw",TSHORT,1,&(s->sw)); toasc(F,"sh",TSHORT,1,&(s->sh)); toasc(F,"sb",TSHORT,1,&(s->sb)); toasc(F,"sp",TSHORT,1,&(s->sp)); toasc(F,"sx",TSHORT,1,&(s->sx)); toasc(F,"sy",TSHORT,1,&(s->sy)); toasc(F,"bs",TSHORT,1,&(s->bs)); toasc(F,"b",TCHAR,s->bs,s->b); toasc(F,"a",TCHAR,1,&(s->a)); toasc(F,"pt",TINT,1,&(s->pt)); toasc(F,"fs",TSHORT,1,&(s->fs)); toasc(F,"f",TINT,1,&(s->f)); toasc(F,"ts",TSHORT,1,&(s->ts)); if (s->ts > 0) toasc(F,"tr",TCHAR,s->ts,s->tr); toasc(F,"act",TINT,1,&(s->act)); toasc(F,"cm",TINT,1,&(s->cm)); toasc(F,"ds",TSHORT,1,&(s->ds)); if (s->ds > 0) toasc(F,"d",TCHAR,s->ds,s->d); toasc(F,"e",TINT,1,&(s->e)); toasc(F,"sl",TFLOAT,1,&(s->sl)); toasc(F,"l",TSHORT,1,&(s->l)); toasc(F,"t",TSHORT,1,&(s->t)); toasc(F,"p",TSHORT,8,s->p); toasc(F,">\n",TNULL,0,NULL); /* prepare next pattern */ ++i; } break; /* patterns types */ case 3: if (i > toppt) { st = 4; i = 0; } else { ptdesc *s; s = pt + i; toasc(F,"at)); toasc(F,"n",TSTR,0,s->n); toasc(F,"f",TINT,1,&(s->f)); toasc(F,"bd",TSHORT,1,&(s->bd)); toasc(F,"a",TINT,1,&(s->a)); toasc(F,"d",TINT,1,&(s->d)); toasc(F,"xh",TINT,1,&(s->xh)); toasc(F,"dd",TINT,1,&(s->dd)); toasc(F,"ls",TSHORT,1,&(s->ls)); toasc(F,"ss",TSHORT,1,&(s->ss)); toasc(F,"ws",TSHORT,1,&(s->ws)); toasc(F,"acc",TINT,1,&(s->acc)); toasc(F,"sc",TINT,256,&(s->sc)); toasc(F,"sa",TINT,256,&(s->sa)); toasc(F,">\n",TNULL,0,NULL); /* prepare next pattern */ ++i; } break; } /* unfinished */ return(1); } /* Session recover. If the parameter st is nonzero, then finish just after reading the unstruct element of the session. */ int recover_session(char *f,int st,int reset) { static FILE *F; static int k,e,pio; static int cm=-1; static trdesc *tr; if (reset) { /* open file */ if (selthresh || ((F = zfopen(f,"r",&pio)) == NULL)) { if (verbose) warn("session file \"%s\" not found (ok)",f); return(0); } DLINE = 0; e = 0; return(1); } /* magic */ if (fromasc(F,"",TNULL,0,NULL) == 0) { } /* unstructured variables */ else if (fromasc(F," 0) fromasc(F,"limits",TINT,8*zones,limits); fromasc(F,"curr_mc",TINT,1,&curr_mc); fromasc(F,"symbols",TINT,1,&symbols); fromasc(F,"doubts",TINT,1,&doubts); fromasc(F,"runs",TINT,1,&runs); fromasc(F,"ocr_time",TINT,1,&ocr_time); fromasc(F,"ocr_r",TINT,1,&ocr_r); fromasc(F,"words",TINT,1,&words); fromasc(F,"classes",TINT,1,&classes); fromasc(F,">",TNULL,0,NULL); if (st) e = 1; } /* start of symbol */ else if (fromasc(F,"= ssz) { int i; i = ssz; mc = c_realloc(mc,(ssz+=1000)*sizeof(sdesc),NULL); for (; i",TNULL,0,NULL); /* copy */ memcpy(mc+k,&m,sizeof(sdesc)); } /* start of closure */ else if (fromasc(F,"",TNULL,0,NULL); /* must enlarge allocated area for cl */ checkcl(++topcl); memcpy(cl+topcl,&m,sizeof(cldesc)); /* create unitary symbol */ /* mc[new_mc(&topcl,1)].isp = 1; */ /* printf("l=%d\n",m.l); */ } /* start of vote */ else if (fromasc(F,"orig)); fromasc(F,"act",TINT,1,&(v->act)); fromasc(F,"q",TCHAR,1,&(v->q)); fromasc(F,">",TNULL,0,NULL); /* add to the current transliteration */ v->nv = NULL; if (tr->v == NULL) tr->v = v; else { for (a=tr->v; a->nv!=NULL; a=(vdesc *)(a->nv)); a->nv = (void *)v; } } /* start of transliteration */ else if (fromasc(F,"pr)); fromasc(F,"n",TINT,1,&(tr->n)); fromasc(F,"f",TINT,1,&(tr->f)); fromasc(F,"a",TCHAR,1,&(tr->a)); fromasc(F,"t",TSTR,0,&(tr->t)); fromasc(F,">",TNULL,0,NULL); /* no votes by now */ tr->v = NULL; /* add to the current symbol */ tr->nt = NULL; if (mc[cm].tr == NULL) mc[cm].tr = tr; else { for (a=mc[cm].tr; a->nt!=NULL; a=a->nt); a->nt = tr; } } /* recover link */ else if (fromasc(F,"= lksz) { lk = c_realloc(lk,(lksz+=128)*(sizeof(lkdesc)),NULL); } if (k > toplk) toplk = k; fromasc(F,"t",TCHAR,1,&(lk[k].t)); fromasc(F,"p",TCHAR,1,&(lk[k].p)); fromasc(F,"a",TINT,1,&(lk[k].a)); fromasc(F,"l",TINT,1,&(lk[k].l)); fromasc(F,"r",TINT,1,&(lk[k].r)); fromasc(F,">\n",TNULL,0,NULL); } /* recover line */ else if (fromasc(F,"= lnsz) { int i = lnsz; lnsz = k + 128; line = c_realloc(line,lnsz*sizeof(lndesc),NULL); for (; i topln) topln = k; fromasc(F,"f",TINT,1,&(line[k].f)); fromasc(F,"l",TINT,1,&(line[k].l)); fromasc(F,">",TNULL,0,NULL); } /* recover word */ else if (fromasc(F,"= wsz) { int i = wsz; wsz = k + 128; word = c_realloc(word,wsz*sizeof(wdesc),NULL); for (; i topw) topw = k; fromasc(F,"F",TINT,1,&(word[k].F)); fromasc(F,"L",TINT,1,&(word[k].L)); fromasc(F,"l",TINT,1,&(word[k].l)); fromasc(F,"r",TINT,1,&(word[k].r)); fromasc(F,"t",TINT,1,&(word[k].t)); fromasc(F,"b",TINT,1,&(word[k].b)); fromasc(F,"E",TINT,1,&(word[k].E)); fromasc(F,"W",TINT,1,&(word[k].W)); fromasc(F,"tl",TINT,1,&(word[k].tl)); fromasc(F,"bl",TINT,1,&(word[k].bl)); fromasc(F,"br",TINT,1,&(word[k].br)); fromasc(F,"f",TINT,1,&(word[k].f)); fromasc(F,"a",TCHAR,1,&(word[k].a)); fromasc(F,"sh",TSHORT,1,&(word[k].sh)); fromasc(F,"as",TSHORT,1,&(word[k].as)); fromasc(F,"ds",TSHORT,1,&(word[k].ds)); fromasc(F,"sk",TINT,1,&(word[k].sk)); fromasc(F,">\n",TNULL,0,NULL); } /* end of dump */ else if (fromasc(F,"",TNULL,0,NULL) == 0) { e = 1; } else { fatal(FD,"unexpected token found ar line %d of %s\n",DLINE,f); } /* completed */ if (e) { /* compute tops */ if (!st) { int i; for (i=ssz-1; (i>=0) && (mc[i].ncl==0); --i); tops = i; for (; (i>=0) ; --i) { if (mc[i].ncl == 0) db("oops.. hole in mc array index %d\n",i); } if (batch_mode == 0) { snprintf(mba,MMB,"finished reading session (topcl=%d tops=%d)", topcl,tops); show_hint(0,mba); } } /* finished */ zfclose(F,pio); sess_changed = 0; return(0); } /* unfinished */ return(1); } /* Acts recover. */ int recover_acts(char *f) { static FILE *F; static int pio; int e; /* prepare to read the buffer "text".. */ if (f == NULL) { F = NULL; topt = 0; } /* ..or open file containing revision data */ else { if ((F = zfopen(f,"r",&pio)) == NULL) { if (verbose) warn("acts file \"%s\" not found (ok)",f); return(0); } } DLINE = 0; for (e=0; e==0; ) { int i; /* magic */ if (fromasc(F,"",TNULL,0,NULL) == 0) { } /* start of act */ else if (fromasc(F,"= actsz) { int j; j = actsz; act = c_realloc(act,(actsz=i+100)*sizeof(adesc),NULL); for (; j topa) topa = i; /* preamble */ fromasc(F,"t",TCHAR,1,&(act[i].t)); fromasc(F,"d",TSTR,0,&(act[i].d)); fromasc(F,"f",TINT,1,&(act[i].f)); /* symbols */ fromasc(F,"mc",TINT,1,&(act[i].mc)); fromasc(F,"a1",TINT,1,&(act[i].a1)); fromasc(F,"a2",TINT,1,&(act[i].a2)); /* transliteration */ fromasc(F,"a",TCHAR,1,&(act[i].a)); fromasc(F,"pt",TSHORT,1,&(act[i].pt)); fromasc(F,"tr",TSTR,0,&(act[i].tr)); /* reviewer data */ fromasc(F,"r",TSTR,0,&(act[i].r)); fromasc(F,"rt",TCHAR,1,&(act[i].rt)); fromasc(F,"sa",TSTR,0,&(act[i].sa)); fromasc(F,"dt",TINT,1,&(act[i].dt)); /* original revision data */ fromasc(F,"or",TSTR,0,&(act[i].or)); fromasc(F,"ob",TSTR,0,&(act[i].ob)); fromasc(F,"om",TINT,1,&(act[i].om)); fromasc(F,"od",TINT,1,&(act[i].od)); fromasc(F,">",TNULL,0,NULL); } /* end of dump */ else if (fromasc(F,"",TNULL,0,NULL) == 0) { e = 1; } else { if (f != NULL) fatal(FD,"unexpected token at line %d of file %s",DLINE,f); else { printf(text); fatal(FD,"unexpected token found on internally generated act"); } } } /* success */ if (F != NULL) { zfclose(F,pio); } hist_changed = 0; return(1); } /* Recover patterns. BUG: when reusing a pdesc structure, won't reuse the memory buffers pointed by the fields b and s. */ int recover_patterns(char *f) { static FILE *F; static int pio; int e; /* open file */ if ((F = zfopen(f,"r",&pio)) == NULL) { if (verbose) warn("bookfont file \"%s\" not found (ok)",f); return(0); } for (e=0; e==0; ) { int i; /* magic */ if (fromasc(F,"",TNULL,0,NULL) == 0) { } /* unstructured variables */ else if (fromasc(F,"",TNULL,0,NULL); } /* start of pattern */ else if (fromasc(F,"tr = s->d = NULL; if (i > topp) topp = i; /* fromasc(F,"dt",TINT,1,&(s->dt)); */ fromasc(F,"id",TINT,1,&(s->id)); fromasc(F,"bw",TSHORT,1,&(s->bw)); fromasc(F,"bh",TSHORT,1,&(s->bh)); fromasc(F,"bb",TSHORT,1,&(s->bb)); fromasc(F,"bp",TSHORT,1,&(s->bp)); fromasc(F,"sw",TSHORT,1,&(s->sw)); fromasc(F,"sh",TSHORT,1,&(s->sh)); fromasc(F,"sb",TSHORT,1,&(s->sb)); fromasc(F,"sp",TSHORT,1,&(s->sp)); fromasc(F,"sx",TSHORT,1,&(s->sx)); fromasc(F,"sy",TSHORT,1,&(s->sy)); fromasc(F,"bs",TSHORT,1,&(s->bs)); fromasc(F,"b",TCHAR,0,&(s->b)); s->s = c_realloc(NULL,s->bs,NULL); fromasc(F,"a",TCHAR,1,&(s->a)); fromasc(F,"pt",TINT,1,&(s->pt)); fromasc(F,"fs",TSHORT,1,&(s->fs)); fromasc(F,"f",TINT,1,&(s->f)); fromasc(F,"ts",TSHORT,1,&(s->ts)); if (s->ts > 0) fromasc(F,"tr",TSTR,0,&(s->tr)); s->ts = (s->tr == NULL) ? 0 : (strlen(s->tr)+1); fromasc(F,"act",TINT,1,&(s->act)); fromasc(F,"cm",TINT,1,&(s->cm)); fromasc(F,"ds",TSHORT,1,&(s->ds)); if (s->ds > 0) fromasc(F,"d",TSTR,0,&(s->d)); s->ds = (s->d == NULL) ? 0 : (strlen(s->d)+1); fromasc(F,"e",TINT,1,&(s->e)); fromasc(F,"sl",TFLOAT,1,&(s->sl)); fromasc(F,"l",TSHORT,1,&(s->l)); fromasc(F,"t",TSHORT,1,&(s->t)); fromasc(F,"p",TSHORT,8,s->p); fromasc(F,">",TNULL,0,NULL); #ifdef CF /* This ugly hack is a companion for that one at event.c (search "Display absent" on that file to locate it). */ if (s->pt == 2) s->f |= F_BOLD; else if (s->pt == 3) s->f |= F_ITALIC; #endif } /* start of pattern type */ else if (fromasc(F," toppt) toppt = i; fromasc(F,"at)); fromasc(F,"n",TSTR,-(MFTL-1),s->n); s->n[MFTL-1] = 0; s->f = 0; fromasc(F,"f",TINT,1,&(s->f)); s->bd = 0; fromasc(F,"bd",TSHORT,1,&(s->bd)); fromasc(F,"a",TINT,1,&(s->a)); fromasc(F,"d",TINT,1,&(s->d)); fromasc(F,"xh",TINT,1,&(s->xh)); fromasc(F,"dd",TINT,1,&(s->dd)); fromasc(F,"ls",TSHORT,1,&(s->ls)); fromasc(F,"ss",TSHORT,1,&(s->ss)); fromasc(F,"ws",TSHORT,1,&(s->ws)); fromasc(F,"acc",TINT,1,&(s->acc)); fromasc(F,"sc",TINT,256,&(s->sc)); fromasc(F,"sa",TINT,256,&(s->sa)); fromasc(F,">",TNULL,0,NULL); } /* end of dump */ else if (fromasc(F,"",TNULL,0,NULL) == 0) { e = 1; } else { fatal(FD,"unexpected token at line %d of file %s\n",DLINE,f); } } /* success */ snprintf(mba,MMB,"%d patterns read",topp+1); show_hint(0,mba); zfclose(F,pio); font_changed = 0; return(1); } /* Free page data structures. */ int free_page(void) { int k; /* free closures */ for (k=0; k<=topcl; ++k) { c_free(cl[k].bm); c_free(cl[k].sup); } topcl = -1; cl_ready = 0; c_free(cl); cl = NULL; clsz = 0; /* free symbols */ for (k=0; k<=tops; ++k) { trdesc *t,*nt; vdesc *v,*nv; /* free each transliteration and votes */ for (t=mc[k].tr; t!=NULL; t=nt) { nt = t->nt; for (v=t->v; v!=NULL; v=nv) { nv = (vdesc *) (v->nv); c_free(v); } c_free(t); } mc[k].tr = NULL; /* free cl */ c_free(mc[k].cl); mc[k].ncl = 0; mc[k].cl = NULL; } tops = -1; curr_mc = -1; c_free(mc); ssz = 0; mc = NULL; /* free lines and words */ c_free(line); line = NULL; lnsz = 0; topln = -1; topw = -1; /* free links */ toplk = -1; /* counters */ symbols = 0; cpage = -1; /* finished */ return(0); } /* From the page name, recover its number. */ int pagenbr(char *p) { int n; int i; if (p == NULL) return(-1); for (i=n=0; n4) && ((strcmp(pagebase+i-4,".pbm")==0) || (strcmp(pagebase+i-4,".pgm")==0))) pagebase[i-4] = 0; if ((i>7) && ((strcmp(pagebase+i-7,".pbm.gz")==0) || (strcmp(pagebase+i-7,".pgm.gz")==0))) pagebase[i-7] = 0; /* session (workdir path plus "1.session" in our example) */ strcpy(session,workdir); strcat(session,pagebase); if (zsession) strcat(session,".session.gz"); else strcat(session,".session"); } /* Load specified page. */ int load_page(int p,int reset,int bin) { int x0,y0; static int mode; char f[MAXFNL+1]; /* prepare */ if (reset) { /* no need to read the current page */ if ((p == cpage) && (pixmap != NULL) && (!bin)) return(0); /* set the new current page */ cpage = p; names_cpage(); /* reset stats */ ocr_time = 0; ocr_r = 0; runs = 0; symbols = 0; doubts = 0; words = 0; /* Try to start recovering the session file */ if (recover_session(session,0,1)) { mode = 1; } /* Try to start reading the bitmap */ else { int t; /* filename */ strncpy(f,pagesdir,MAXFNL); strncat(f,pagename,MAXFNL); t = strlen(f); /* start binarization/segmentation */ if ((pixmap != NULL) && (bin)) { /* use the local thresholder */ if (localbin_strong) { find_thing(pixmap,1,-1,-1); mode = 2; } /* use the global thresholder */ else { sh_tries = 0; pbm2bm(pixmap,1); mode = 2; } } /* start reading pixmap from file */ else { loadpgm(1,f,&pixmap,&XRES,&YRES); mode = 3; } } return(1); } /* continue recovering the session file */ if (mode == 1) { /* not finished yet */ if (recover_session(NULL,0,0)) return(1); /* finished reading the session file */ cl_ready = 1; synchronize(); } /* continue reading the bitmap */ else if (mode == 2) { /* not finished yet */ if (localbin_strong) { if (find_thing(NULL,0,-1,-1)) return(1); } /* global thresholding */ else { if (pbm2bm(NULL,0)) return(1); } /* finished reading the bitmap */ cl_ready = 1; } /* continue reading the pixmap */ else { /* continue reading */ if (loadpgm(0,f,&pixmap,&XRES,&YRES)) return(1); /* PAGE only is mandatory for graymaps */ if (pm_t == 8) *cm_o_pgo = 'X'; /* no predefined zone */ zones = 0; /* finished */ sess_changed = 0; return(0); } /* set the window title */ if (batch_mode == 0) swn(pagebase); /* list the preferred symbols */ make_pmc(); /* consist curr_mc */ if ((curr_mc < 0) || (tops < curr_mc)) curr_mc = 0; if (curr_mc > tops) curr_mc = -1; /* Initialize windows avoiding to lost the current position on PAGE_LIST because this window is the one being exhibited during a full OCR. */ x0 = dw[PAGE_LIST].x0; y0 = dw[PAGE_LIST].y0; init_dws(0); dw[PAGE_LIST].x0 = y0; dw[PAGE_LIST].y0 = y0; /* prepare data structures for list_cl */ list_cl(0,0,0,0,1); /* parameters for page list display */ dl_ne[p] = symbols; dl_db[p] = doubts; dl_r[p] = runs; dl_t[p] = ocr_time; dl_lr[p] = ocr_r; dl_w[p] = words; dl_c[p] = classes; /* finished */ sess_changed = 0; return(0); }