2
Copyright (c) 1993-2008, Cognitive Technologies
5
����������� ��������� ��������������� � ������������� ��� � ���� ��������� ����,
6
��� � � �������� �����, � ����������� ��� ���, ��� ���������� ��������� �������:
8
* ��� ��������� ��������������� ��������� ���� ������ ���������� ���������
9
���� ����������� �� ��������� �����, ���� ������ ������� � �����������
11
* ��� ��������� ��������������� ��������� ���� � ������������ �/��� �
12
������ ����������, ������������ ��� ���������������, ������ �����������
13
��������� ���� ���������� �� ��������� �����, ���� ������ ������� �
14
����������� ����� �� ��������.
15
* �� �������� Cognitive Technologies, �� ����� �� ����������� �� �����
16
���� ������������ � �������� �������� ��������� �/��� �����������
17
���������, ���������� �� ���� ��, ��� ���������������� �����������
20
��� ��������� ������������� ����������� ��������� ���� �/��� ������� ������ "���
21
��� ����" ��� ������-���� ���� ��������, ���������� ���� ��� ���������������,
22
������� �������� ������������ �������� � ����������� ��� ���������� ����, �� ��
23
������������� ���. �� �������� ��������� ���� � �� ���� ������ ����, �������
24
����� �������� �/��� �������� �������������� ���������, �� � ���� ������ ��
25
��Ѩ� ���������������, ������� ����� �����, ���������, ����������� ���
26
������������� ������, ��������� � �������������� ��� ���������� ����������
27
������������� ������������� ��������� (������� ������ ������, ��� ������,
28
������� ���������, ��� ������ �/��� ������ �������, ���������� ��-�� ��������
29
������� ��� �/��� ������ ��������� �������� ��������� � ������� �����������,
30
�� �� ������������� ����� ��������), �� �� ������������� ���, ���� ���� �����
31
�������� ��� ������ ���� ���� �������� � ����������� ����� ������� � ������.
33
Redistribution and use in source and binary forms, with or without modification,
34
are permitted provided that the following conditions are met:
36
* Redistributions of source code must retain the above copyright notice,
37
this list of conditions and the following disclaimer.
38
* Redistributions in binary form must reproduce the above copyright notice,
39
this list of conditions and the following disclaimer in the documentation
40
and/or other materials provided with the distribution.
41
* Neither the name of the Cognitive Technologies nor the names of its
42
contributors may be used to endorse or promote products derived from this
43
software without specific prior written permission.
45
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
46
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
49
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
51
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
52
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
53
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
54
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70
#include "compat_defs.h"
75
typedef struct tagRecogStat
77
INT nbig,ndust,weight;
87
static INT dirt_frag(cell **B, cell **E, cell *first, cell *last, BOOL stop_first);
88
static void bl_cut(cell *B, cell *E, INT cut);
89
static BOOL find_clust(BYTE let);
90
static BOOL clip_cell(INT j, cell *c, INT b1, INT b2, INT b3, INT b4, INT st_inc);
91
static void save_frag(cell *B, cell *E, RecogStat *rs, cell **sv_frag, INT *st_inc);
92
static void replace_frag(cell *B, cell *E, RecogStat *rs, cell *sv_frag);
93
static INT create_cells(cell *whither, raster *r, cell *celist[], INT st_inc);
94
static cell *hide(cell *c, cell **clink);
95
static void restore(cell *clink, cell *wherever);
96
static void del_hided(cell *clink);
97
static BOOL capital(BYTE let);
101
cell *BI,*EI,*B0=cell_f()->nextl,*E0=cell_l();
103
get_b_lines(NULL,&bl);
104
fb1=bl.n1>0 && bl.n1<255;
105
fb2=bl.n2>0 && bl.n2<255;
106
fb3=bl.n3>0 && bl.n3<255;
107
fb4=bl.n4>0 && bl.n4<255;
109
if (fict(B0) || !(cut=dirt_frag(&B0,&E0,B0,E0->prevl,FALSE)))
112
BI=B0; EI=E0=E0->nextl;
113
if (E0->nextl) E0=E0->nextl;
114
while(dirt_frag(&BI,&EI,cell_f()->nextl,cell_l()->prevl,TRUE))
117
if (fict(BI->prevl)) BI=cell_f()->next;
119
if (fict(EI->nextl)) { R=cell_l(); EI=R->prev; }
120
else { EI=EI->nextl; R=EI->nextl; }
126
static BOOL dirt_frag(cell **B,cell **E)
128
cell *c=cell_f()->next;
130
glsnap('o',c,"Cut by bases; input r_col for begin and end");
131
if (gbCol1==0 && gbCol2==0 || gbCol1>gbCol2)
135
for ( ; c->next; c=c->next)
137
if (c->r_col==gbCol1) *B=c;
138
if (c->r_col==gbCol2) { *E=c; break; }
145
LONG testDirt(CSTR_rast *beg, CSTR_rast *end)
147
CSTR_rast rst=*beg,first=rst,last=CSTR_GetNext(*end);
148
CSTR_rast capb=0,cape=0;
149
INT dirtup=0,dirtdown=0,ncap=0;
151
get_b_lines(NULL,&bl);
152
fb1=bl.n1>0 && bl.n1<255;
153
fb2=bl.n2>0 && bl.n2<255;
154
fb3=bl.n3>0 && bl.n3<255;
155
fb4=bl.n4>0 && bl.n4<255;
159
for ( ; rst != last; rst=CSTR_GetNext(rst))
163
CSTR_GetAttr(rst,&attr);
165
if (fb1 && attr.row+bl_lim < bl.b1) { dirtup++; goto mark; }
166
if (fb4 && attr.row+attr.h-bl_lim > bl.b4) { dirtdown++; goto mark; }
168
CSTR_GetCollectionUni(rst,&uni);
170
if (uni.Alt[0].Prob<trs2)
172
BYTE let=uni.Alt[0].Code[0],letpos = let_linpos[let];
173
INT bot=attr.row+attr.h;
174
BOOL d2=attr.row<bl.b2-bl_lim,d3=bot>bl.b3+bl_lim;
178
if (d2) { dirtup++; goto mark; }
179
if (d3) { dirtdown++; goto mark; }
181
if (rst != first && capital(let))
187
switch(letpos & 0x0F)
190
if (fb3 && d3) { dirtdown++; goto mark; };
192
case 2: case 5: case 6: case 7:
193
if (fb4 && bot>bl.b4-bl_lim) { dirtdown++; goto mark; };
196
if (!strchr("3568�������",let))
202
if (fb1 && abs(attr.row-bl.b1)>bl_lim) { dirtup++; goto mark; }
205
if (fb2 && d2) { dirtup++; goto mark; }
207
case 3: case 4: case 5:
208
if (fb1 && attr.row<bl.b1+bl_lim) { dirtup++; goto mark; }
216
if (!(*beg)) *beg=rst;
220
if (dirtup==0 && ncap>1) dirtup += ncap;
221
if (!(*beg)) { *beg=capb; *end=cape; }
222
if (dirtup > 2*dirtdown) return 1;
223
if (dirtdown > 2*dirtup) return -1;
227
static INT dirt_frag(cell **B, cell **E, cell *first, cell *last, BOOL stop_first)
230
cell *capb=NULL,*cape=NULL;
231
INT dirtup=0,dirtdown=0,ncap=0;
234
glsnap('o',c,"Cut by bases; input r_col for begin and end");
235
if (gbCol1 != 0 && gbCol2 != 0 && abs(gbCol1)<=abs(gbCol2))
236
return gbCol1/abs(gbCol1);
239
for ( ; c != end && !fict(c); c=c->nextl)
241
if (c==last && 4*c->w < c->h) continue;
243
if (fb1 && c->row+bl_lim < bl.b1) { dirtup++; goto mark; }
244
if (fb4 && c->row+c->h-bl_lim > bl.b4) { dirtdown++; goto mark; }
246
if (c->vers[0].prob<trs2)
248
BYTE let=c->vers[0].let;
249
BYTE letpos = let_linpos[let];
251
BOOL d2 = (fb2) ? c->row<bl.b2-bl_lim : TRUE;
252
BOOL d3 = (fb3) ? bot>bl.b3+bl_lim : TRUE;
254
if ((c->pr_vers.prob>=220 ||
255
strchr("���",c->pr_vers.let) &&
256
!is_russian_baltic_conflict(c->pr_vers.let)&&// 17.07.2001 E.P.
257
!is_russian_turkish_conflict(c->pr_vers.let) // 21.05.2002 E.P.
258
) && !find_clust(c->pr_vers.let)
264
BYTE let=c->pr_vers.let;
265
// if (c->pr_vers.prob>=220) continue;
270
if (c->pr_vers.prob>100 && strchr("3568EH�������",let))
272
if (strchr("EH������",let) || 5*c->w < 4*c->h)
276
sticks_in_letter(c,0,&st);
277
if (c->n_baton==1 && abs(c->save_baton[0].l-c->h)<=bl_lim ||
278
c->n_baton==2 && abs(c->save_baton[1].l-c->h)<=bl_lim)
289
// 16.07.2001 E.P. �������� � a_bottom_accent_baltic 0xe0
290
!is_baltic_language(language) &&
292
(c->pr_vers.prob>100 || abs(c->save_baton[0].l-c->h)<=bl_lim)
301
if ((c != first || stop_first) && capital(let))
308
// 16.07.2001 E.P. �������� � a_bottom_accent_baltic 0xe0
309
is_baltic_language(language)
311
switch(letpos & 0x0F)
314
if (fb3 && d3) { dirtdown++; goto mark; };
316
case 2: case 5: case 6: case 7:
317
if (fb4 && bot>bl.b4-bl_lim) { dirtdown++; goto mark; };
321
if (!strchr("3568�������",let))
325
if (fb1 && abs(c->row-bl.b1)>bl_lim) { dirtup++; goto mark; }
328
if (fb2 && d2) { dirtup++; goto mark; }
330
case 3: case 4: case 5:
331
if (fb1 && c->row<bl.b1+bl_lim) { dirtup++; goto mark; }
338
LONG nc=FONGetNumCluster(c->r_clink);
339
FONGetClustInfo(&cli,nc);
349
if (stop_first && *B) break;
357
if (dirtup==0 && ncap>1) dirtup += ncap;
358
if (!(*B)) { *B=capb; *E=cape; }
360
if (*B && !fict((*B)->prevl)) *B=(*B)->prevl;
361
if (*E && !fict((*E)->nextl)) *E=(*E)->nextl;
363
if (dirtup > 2*dirtdown) return 1;
364
if (dirtdown > 2*dirtup) return -1;
368
static BOOL find_clust(BYTE let)
373
return FONGetClustInfo( &clustinfo,1) > 0;
379
static void bl_cut(cell *B, cell *E, INT cut)
381
cell *f=B,*LC=B->prev,*RC=E->next;
384
INT st_inc; //�।��� ������
388
save_frag(B,E,&rs,&sv_frag,&st_inc);
390
//make cut by base lines
395
c->cg_flag &= ~c_cg_cutdone; //c_cg_cutdone flag prevents cell to cut in smart_cut
396
if (let_or_bad(c) && c->vers[0].prob>=trs2)
398
c->flg &= ~c_f_bad; c->flg |= c_f_let;
402
INT b1 = (fb1 && cut>0) ? bl.b1-c->row : 0;
403
INT b2 = (fb2 && cut>0) ? bl.b2-c->row : 0;
404
INT b3 = (fb3 && cut<0) ? bl.b3-c->row : 0;
405
INT b4 = (fb4 && cut<0) ? bl.b4-c->row : 0;
409
c->flg &= ~c_f_let; c->flg |= c_f_bad;
412
if (b1>0 || b2>0 || b3<c->h || b4<c->h)
414
glsnap('o',c,"try clip");
415
repair &= clip_cell(0,c,b1,b2,b3,b4,st_inc);
422
if (LC->next != RC && LC != RC->prev)
424
process_word(LC->next,RC->prev);
425
replace_frag(LC->next,RC->prev,&rs,sv_frag);
432
static BOOL clip_cell(INT j, cell *c, INT b1, INT b2, INT b3, INT b4, INT st_inc)
434
//��१��� �� c ��, �� ��室�� �� b1,b4 (����� �� c->row); b2,b3 - �������⥫�� ࠧ१�,
437
INT crow=c->row; //b1,b2,b3,b4 refer to crow
440
// for (j=0; j<2 && c; j++)
447
if (b1<=2 || b1>=c->h) b1=0;
448
if (b4>=c->h-2) b4=0;
449
cut_made = b1>0 || b4>0;
453
if (b2<=2 || b2>=c->h) b2=0;
454
if (b3<=0 || b3>c->h-2) b3=0;
455
cut_made = b2>0 || b3>0;
460
raster r; //������� ����
461
cell *celist[MAX_SECT+1];
462
INT wbyte=(c->w+7)>>3,i,nall,size=((c->w+7)>>3)*c->h;
465
if (size>sizeof(r.pict))
467
memcpy(&(r.pict),(BYTE*)save_raster(c),size);
468
r.w=c->w; r.h=c->h; r.top=c->r_row; r.left=c->r_col;
472
if (b1>0) memset(r.pict,0,b1*wbyte);
473
if (b4>0) memset(&(r.pict[(b4+1)*wbyte]),0,(c->h-b4-1)*wbyte);
477
if (b2>0) memset(&(r.pict[b2*wbyte]),0,wbyte);
478
if (b3>0) memset(&(r.pict[(b3+1)*wbyte]),0,wbyte);
481
if (!(nall=create_cells(c,&r,celist,st_inc)))
484
for (i=0; i<nall; i++)
487
t->flg_new |= CSTR_fn_bl_cut;
488
t->cg_flag=c->cg_flag;
489
if (t->r_col != c->r_col) t->cg_flag &= ~c_cg_cutl;
490
if (t->r_col+t->w != c->r_col+c->w) t->cg_flag &= ~c_cg_cutr;
493
// if (t->row+t->h==crow+b2 || t->row==crow+b3+2)
499
full_recog(t,NULL,trs2,trs2);
500
if (!let(t)) repair &= clip_cell((INT)(j+1),t,0,(INT)(crow+b2-t->row),(INT)(crow+b3-t->row),0,st_inc);
505
return repair && nbig != 0;
508
return clip_cell((INT)(j+1),c,0,(INT)(crow+b2-c->row),(INT)(crow+b3-c->row),0,st_inc);
513
static INT create_cells(cell *whither, raster *r, cell *celist[], INT st_inc)
516
MN *mn=c_locomp(r->pict,(INT)((r->w+7)>>3),r->h,r->top,r->left);
517
for (i=0; i<MAX_SECT && mn; i++,mn=mn->mnnext)
519
cell *c=create_my_cell(mn,whither,0,0);
521
set_erection(c, st_inc);
527
static void save_frag(cell *B, cell *E, RecogStat *rs, cell **sv_frag, INT *st_inc)
529
cell *celist[MAX_SECT];
533
rs->weight=256; rs->nbig=rs->ndust=0;
534
for ( ; B != E; B=B->next)
538
c->complist=(c_comp *)(*sv_frag);
543
rs->weight = MIN(rs->weight,B->vers[0].prob);
546
if (fb2 && fb3 && c->row > bl.b2 && c->row+c->h < bl.b3)
548
if (n<MAX_SECT) celist[n++]=B;
550
*st_inc = erection_compose_inc(n, celist);
553
static void replace_frag(cell *B, cell *E, RecogStat *rs, cell *sv_frag)
556
INT weight=256,nbig=0,ndust=0;
560
for (c=B; c != E; c=c->next)
564
weight = MIN(weight,c->vers[0].prob);
567
if (fb2 && fb3 && c->row > bl.b2 && c->row+c->h < bl.b3)
570
if (nbig < rs->nbig && ndust > rs->ndust || //some big cells's cut to dust
571
weight <= rs->weight)
573
for (c=B; c != E; c=c->next) c=del_cell(c);
580
static cell *hide(cell *c, cell **clink)
583
c->complist=(c_comp *)(*clink);
589
static void restore(cell *clink, cell *wherever)
593
insert_cell(clink,wherever);
594
clink=(cell *)clink->complist;
598
static void del_hided(cell *clink)
603
clink=(cell *)clink->complist;
607
static BOOL capital(BYTE let)
609
return (let>='0' && let<='9' || let>='A' && let<='Z' || let>='�' && let<='�');