re-added file
[swftools.git] / lib / gocr / gocr.h
1 /*
2 This is a Optical-Character-Recognition program
3 Copyright (C) 2000-2006 Joerg Schulenburg
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19  see README for EMAIL-address
20
21   sometimes I have written comments in german language, sorry for that
22
23  - look for ??? for preliminary code
24 */
25  
26 /* General headerfile with gocr-definitions */
27
28 #ifndef __GOCR_H__
29 #define __GOCR_H__
30
31 #include "pnm.h"
32 #include "unicode.h"
33 #include "list.h"
34 #include <stddef.h>
35 #ifdef HAVE_GETTIMEOFDAY
36 #include <sys/time.h>
37 #endif
38
39 /*
40  *  wchar_t should always exist (ANSI), but WCHAR.H is sometimes missing
41  *  USE_UNICODE should be removed or replaced by HAVE_WCHAR_H in future
42  */
43 #ifdef HAVE_WCHAR_H
44 #define USE_UNICODE 1
45 #endif
46
47 /* extern "C"{ */
48 /* ------------------------ feature extraction ----------------- */
49 #define AT 7    /* mark */
50 #define M1 1    /* mark */
51 enum direction {
52   UP=1, DO, RI, LE
53 };
54 typedef enum direction DIRECTION;
55 #define ST 7    /* stop */
56 /* ------------------------------------------------------------- */
57 /* detect maximas in of line overlapps (return in %) and line koord */
58 #define HOR 1    /* horizontal */
59 #define VER 2    /* vertikal   */
60 #define RIS 3    /* rising=steigend */
61 #define FAL 4    /* falling=fallend */
62
63 #define MAXlines 1024
64
65 /* ToDo: if we have a tree instead of a list, a line could be a node object */
66 struct tlines {
67     int num;
68     int dx, dy;         /* direction of text lines (straight/skew) */
69     int m1[MAXlines],   /* start of line = upper bound of 'A' */
70         m2[MAXlines],   /* upper bound of 'e' */
71         m3[MAXlines],   /* lower bound of 'e' = baseline */
72         m4[MAXlines];   /* stop of line = lower bound of 'q' */
73     int x0[MAXlines],
74         x1[MAXlines];   /* left and right border */
75     int wt[MAXlines];   /* weight, how sure thats correct in percent, v0.41 */
76     int pitch[MAXlines]; /* word pitch (later per box?), v0.41 */
77     int mono[MAXlines];  /* spacing type, 0=proportional, 1=monospaced */
78 };
79
80 #define NumAlt 10 /* maximal number of alternative chars (table length) */
81 #define MaxNumFrames 8       /* maximum number of frames per char/box */
82 #define MaxFrameVectors 128  /* maximum vectors per frame (*8=1KB/box) */
83 /* ToDo: use only malloc_box(),free_box(),copybox() for creation, destroy etc.
84  *       adding reference_counter to avoid pointer pointing to freed box
85  */
86 struct box { /* this structure should contain all pixel infos of a letter */
87     int x0,x1,y0,y1,x,y,dots; /* xmin,xmax,ymin,ymax,reference-pixel,i-dots */
88     int num_boxes, /* 1 "abc", 2 "!i?", 3 "&auml;" (composed objects) 0.41 */
89         num_subboxes;   /* 1 for "abdegopqADOPQR", 2 for "B"  (holes) 0.41 */
90     wchar_t c;          /* detected char (same as tac[0], obsolete?) */
91     wchar_t modifier;   /* default=0, see compose() in unicode.c */
92     int num;            /* same number = same char */
93     int line;           /* line number (points to struct tlines lines) */
94     int m1,m2,m3,m4;    /* m2 = upper boundary, m3 = baseline */
95     /* planed: sizeof hole_1, hole_2, certainty (run1=100%,run2=90%,etc.) */
96     pix *p;             /* pointer to pixmap (v0.2.5) */
97     /* tac, wac is used together with setac() to manage very similar chars */
98     int num_ac;         /* length of table (alternative chars), default=0 */
99     wchar_t tac[NumAlt]; /* alternative chars, only used by setac(),getac() */
100     int     wac[NumAlt]; /* weight of alternative chars */
101     char   *tas[NumAlt]; /* alternative UTF8-strings or XML codes if tac[]=0 */
102                          /*   replacing old obj */
103                          /* ToDo: (*obj)[NumAlt] + olen[NumAlt] ??? */
104                          /* ToDo: bitmap for possible Picture|Object|Char ??? */
105 /*  char    *obj; */     /* pointer to text-object ... -> replaced by tas[] */
106                          /*  ... (melted chars, barcode, picture coords, ...) */
107                          /*  must be freed before box is freed! */
108                          /*  do _not_ copy only the pointer to object */
109     /* --------------------------------------------------------
110      *  extension since v0.41 js05, Store frame vectors,
111      *  which is a table of vectors sourrounding the char and its
112      *  inner white holes. The advantage is the independence from
113      *  resolution, handling of holes, overlap and rotation.
114      * --------------------------------------------------------- */
115     int num_frames;      /* number of frames: 1 for cfhklmnrstuvwxyz */
116                          /*                   2 for abdegijopq */
117     int frame_vol[MaxNumFrames]; /* volume inside frame +/- (black/white) */
118     int frame_per[MaxNumFrames]; /* periphery, summed length of vectors */
119     int num_frame_vectors[MaxNumFrames]; /* index to next frame */
120                 /* biggest frame should be stored first (outer frame) */
121                 /* biggest has the maximum pair distance */
122                 /* num vector loops */
123     int frame_vector[MaxFrameVectors][2]; /* may be 16*int=fixpoint_number */
124     
125 };
126 typedef struct box Box;
127
128 /* true if the coordination pair (a,b) is outside the image p */
129 #define outbounds(p, a, b)  (a < 0 || b < 0 || a >= (p)->x || b >= (p)->y)
130
131 /* ToDo: this structure seems to be obsolete, remove it */
132 typedef struct path {
133   int start;    /* color at the beginning of the path, (0=white, 1=black) */
134   int *x;       /* x coordinates of transitions */
135   int *y;       /* y coordinates of transitions */
136   int num;      /* current number of entries in x or y */
137   int max;      /* maximum number of entries in x or y */
138   /* (if more values need to be stored, the arrays are enlarged) */
139 } path_t;
140
141 /* job_t contains all information needed for an OCR task */
142 typedef struct job_s {
143   struct {       /* source data */
144     char *fname; /* input filename; default value: "-" */
145     pix p;       /* source pixel data, pixelmap 8bit gray */
146   } src;
147   struct { /* temporary stuff, e.g. buffers */
148 #ifdef HAVE_GETTIMEOFDAY
149     struct timeval init_time; /* starting time of this job */
150 #endif
151     pix ppo; /* pixmap for visual debugging output, obsolete */
152
153     /* sometimes recognition function is called again and again, if result was 0
154        n_run tells the pixel function to return alternative results */
155     int n_run;   /* num of run, if run_2 critical pattern get other results */
156                  /* used for 2nd try, pixel uses slower filter function etc. */
157     List dblist; /* list of boxes loaded from the character database */
158   } tmp;
159   struct {         /* results */
160     List boxlist;  /* store every object in a box, which contains */
161                    /* the characteristics of the object (see struct box) */
162     List linelist; /* recognized text lines after recognition */
163     
164     struct tlines lines; /* used to access to line-data (statistics) */
165                          /* here the positions (frames) of lines are */
166                          /* stored for further use */
167     int avX,avY;         /* average X,Y (avX=sumX/numC) */
168     int sumX,sumY,numC;  /* sum of all X,Y; num chars */
169   } res;
170   struct {    /* configuration */
171     int cs;   /* critical grey value (pixel<cs => black pixel) */
172               /* range: 0..255,  0 means autodetection */
173     int spc;  /* spacewidth/dots (0 = autodetect); default value: 0 */
174     int mode; /* operation modes; default value: 0 */
175               /* operation mode (see --help) */
176     int dust_size;    /* dust size; default value: 10 */
177     int only_numbers; /* numbers only; default value: 0 */
178     int verbose; /* verbose mode; default value: 0 */ 
179                  /* verbose option (see --help) */
180     FORMAT out_format; /* output format; default value: ISO8859_1*/
181     char *lc; /* debuglist of chars (_ = not recognized chars) */
182               /* default value: "_" */
183     char *db_path; /* pathname for database; default value: NULL */
184     char *cfilter; /* char filter; default value: NULL, ex: "A-Za-z" */
185         /* limit of certainty where chars are accepted as identified */
186     int  certainty; /* in units of 100 (percent); 0..100; default 95 */
187   } cfg;
188 } job_t;
189
190 /* initialze job structure */
191 void job_init(job_t *job);
192
193 /* free job structure */
194 void job_free(job_t *job);
195
196 /*FIXME jb: remove JOB; */
197 extern job_t *JOB;
198
199 /* calculate the overlapp of the line (0-1) with black points 
200  * by rekursiv bisection 
201  * (evl. Fehlertoleranz mit pixel in Umgebung dx,dy suchen) (umschaltbar) ???
202  * MidPoint Line Algorithm (Bresenham) Foley: ComputerGraphics better?
203  * will be replaced by vector functions
204  */
205
206 /* gerade y=dy/dx*x+b, implizit d=F(x,y)=dy*x-dx*y+b*dx=0 
207  * incrementell y(i+1)=m*(x(i)+1)+b, F(x+1,y+1)=f(F(x,y))  */
208 int get_line(int x0, int y0, int x1, int y1, pix *p, int cs, int ret);
209 int get_line2(int x0, int y0, int x1, int y1, pix *p, int cs, int ret);
210
211 /* look for white 0x02 or black 0x01 dots (0x03 = white+black) */
212 char get_bw(int x0, int x1, int y0, int y1,
213              pix *p, int cs,int mask);
214
215 /* look for black crossing a line x0,y0,x1,y1
216  * follow line and count crossings ([white]-black-transitions)
217  */
218 int num_cross(int x0, int x1, int y0, int y1,
219                pix *p,  int cs);
220
221 /* memory allocation with error checking */
222 void *xrealloc(void *ptr, size_t size);
223
224 /* follow a line x0,y0,x1,y1 recording locations of transitions,
225  * return count of transitions 
226  */
227 int follow_path(int x0, int x1, int y0, int y1, pix *p,  int cs, path_t *path);
228
229 /* -------------------------------------------------------------
230  * mark edge-points
231  *  - first move forward until b/w-edge
232  *  - more than 2 pixel?
233  *  - loop around
234  *    - if forward    pixel : go up, rotate right
235  *    - if forward no pixel : rotate left
236  *  - stop if found first 2 pixel in same order
237  * mit an rechter-Wand-entlang-gehen strategie
238  * --------------------------------------------------------------
239  * turmite game: inp: start-x,y, regel r_black=UP,r_white=RIght until border
240  *               out: last-position
241  * Zaehle dabei, Schritte,Sackgassen,xmax,ymax,ro-,ru-,lo-,lu-Ecken
242  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
243  *
244  * is this the right place for declaration?
245  */
246 void turmite(pix *p, int *x, int *y, 
247              int x0, int x1, int y0, int y1, int cs, int rw, int rb);
248
249 /* test if points are connected via t-pixel (rekursiv!) */
250 int joined(pix *p, int x0, int y0, int x1, int y1, int cs);
251
252 /* move from x,y to direction r until pixel or l steps
253  * return number of steps
254  */
255 int loop(pix *p, int x, int y, int l, int cs, int col, DIRECTION r);
256
257 #define MAX_HOLES 3
258 typedef struct list_holes { 
259   int num;    /* numbers of holes, initialize with 0 */ 
260   struct hole_s {
261     int size,x,y,x0,y0,x1,y1; /*  size, start point, outer rectangle */
262   } hole[MAX_HOLES];
263 } holes_t;
264           
265 /* look for white holes surrounded by black points
266  * at moment white point with black in all four directions
267  */
268 int num_hole(int x0, int x1, int y0, int y1, pix *p, int cs, holes_t *holes);
269
270 /* count for black nonconnected objects --- used for i,auml,ouml,etc. */
271 int num_obj(int x0, int x1, int y0, int y1, pix  *p, int cs);
272
273 int distance(   pix *p1, struct box *box1,      /* box-frame */
274                 pix *p2, struct box *box2, int cs);
275
276 /* call the OCR engine ;) */
277 /* char whatletter(struct box *box1,int cs); */
278
279 /* declared in pixel.c */
280 /* getpixel() was pixel() but it may collide with netpnm pixel declaration */
281 int getpixel(pix *p, int x, int y);
282 int marked(pix *p, int  x, int  y);
283 void put(pix * p, int x, int y, int ia, int io);
284
285 /* } */ /* extern C */
286 #endif /* __GOCR_H__ */