2
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
�������� ��� ������ ���� ���� �������� � ����������� ����� ������� � ������.
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
33
Redistribution and use in source and binary forms, with or without modification,
34
34
are permitted provided that the following conditions are met:
177
177
sort_int - fast sorting
179
179
OpenFullOutTiger - RTF
180
CalcStatTiger - ���������� �� ���������� (������- � ���- ������� � �.�.)
180
CalcStatTiger - статистика об интервалах (внутри- и меж- словные и т.п.)
182
extern "C" BOOL PageTree(FILE *InFileName, CRtfPage* RtfPage, const char* OutFileName);
182
extern "C" Bool PageTree(FILE *InFileName, CRtfPage* RtfPage, const char* OutFileName);
183
183
extern short __cdecl OpenFullOutTiger(FILE *FileName);
184
void show_frm(Int16 NumFragm,FRAME **frm);
184
void show_frm(int16_t NumFragm,FRAME **frm);
185
185
Bool Alik_sort_function( const void *a, const void *b);
186
186
int CalcStatTiger(void);
187
Int16 GenerateTreeByFragm(Rect16 *RectFragm,Int16 NumFragm,
187
int16_t GenerateTreeByFragm(Rect16 *RectFragm,int16_t NumFragm,
188
188
SETUP_GENERATE_TREE *setup, FRAME ***Frm1, INF_TREE *Inf);
189
void GetFirstIndexFragm(Rect16 *RectFragm,Int16 NumCol,Int16 *nc,FRAME **frm);
190
Int16 CreateTreePlainTxt1(BOUND BndTxt,STRET *LineV,Int16 NumLV,STRET *LineH,
191
Int16 NumLH,FRAME **frm,Int16 NumFrm,INF_TREE *Inf,Int16 size_x,Int16 size_y);
192
Int16 AddLine1(LINE_KNOT **Line1,Int16 *nCurr,Int16 *nMax,Int16 Coor,Int16 Thres);
193
Int16 SearchColHist1(FRAME **frm,Int16 k_frm,BOUND *bnd,Int16 ave_x,Int16 ave_y,
194
Int16 reg,Int16 *k_int,Int16 **intr1,Int16 **begI,Int16 **endI,Int16 *NumMax);
195
Int16 SearchInterval1(FRAME **frm,Int16 k_frm,Int16 **beg1,Int16 **end1,
196
Int16 *k_int1,BOUND *bnd,Int16 ave_dir,Int16 ave_ort,Int16 reg,Int16 *NumMax);
189
void GetFirstIndexFragm(Rect16 *RectFragm,int16_t NumCol,int16_t *nc,FRAME **frm);
190
int16_t CreateTreePlainTxt1(BOUND BndTxt,STRET *LineV,int16_t NumLV,STRET *LineH,
191
int16_t NumLH,FRAME **frm,int16_t NumFrm,INF_TREE *Inf,int16_t size_x,int16_t size_y);
192
int16_t AddLine1(LINE_KNOT **Line1,int16_t *nCurr,int16_t *nMax,int16_t Coor,int16_t Thres);
193
int16_t SearchColHist1(FRAME **frm,int16_t k_frm,BOUND *bnd,int16_t ave_x,int16_t ave_y,
194
int16_t reg,int16_t *k_int,int16_t **intr1,int16_t **begI,int16_t **endI,int16_t *NumMax);
195
int16_t SearchInterval1(FRAME **frm,int16_t k_frm,int16_t **beg1,int16_t **end1,
196
int16_t *k_int1,BOUND *bnd,int16_t ave_dir,int16_t ave_ort,int16_t reg,int16_t *NumMax);
197
197
KNOTT* IncKnot(KNOTT *up,KNOTT *after,KNOTT **free);
198
void FillFieldKNOTT1(KNOTT *ptr,Int16 Left,Int16 Right,Int16 Top,Int16 Bottom,
199
Int16 InBegFrm,Int16 NumFrm,Int16 InColA,
198
void FillFieldKNOTT1(KNOTT *ptr,int16_t Left,int16_t Right,int16_t Top,int16_t Bottom,
199
int16_t InBegFrm,int16_t NumFrm,int16_t InColA,
200
200
uint OrderChild,uint Type,uint AllowOCR,uint JustH,uint JustV,char *Name);
201
Int16 SortHorLine1(LINE_KNOT *LineHK,Int16 NumH,LINE_KNOT *LineVK,Int16 NumV,
202
KNOTT *Root,KNOTT ***colt1,Int16 *k_colt1,FRAME **frm);
203
char *get2_param(char *str,char *param,Int16 max_len);
204
Int16 Check_IsItFalseHorLine(Int16 recalc,Int16 reg,FRAME **frm,Int16 *his,Int16 pos,Int16 len,
205
Int16 maxh,Int16 sum,Int16 len_group,Int16 *his_first_group,
206
Int16 *his_second_group,BOUND *bnd,Int16 k_frm);
207
Int16 check_white_int(Int16 beg_white_int,Int16 end_white_int,Int16 maxh,
208
Int16 *his_second_group);
209
Int16 GetRealSize( char* str,Int16 len,Int16 FontSize ,Int16 FontNumber,Int16* strHeight);
210
void Get_all_term_fragms( KNOTT *ptr,Int16 *Colt,Int16 *iv ,Int16 NumCol,FRAME **frm);
211
void Get_all_term_fragms1( KNOTT* ptr,Int16* Colt,Int16* iv,Int16 NumCol,FRAME **frm);
212
Int16 term_col_seriated(Int16* term_ind,Int16 Count_Term_Col,Int16* K_Ver_Flag_Term);
213
Int16 OrderingAndRecalcCol(Int16 Nsector,Int16 Ncol,Int16 H0,Int16 L0,Int16 *W_P,Int16 *H_P,
214
Int16 dist_col,KNOTT *pRoot,FRAME **frm,
215
Float32 Max_koof_for_width,Float32 Max_koof_for_height);
216
Int16 RecalcRect(Int16 L,Int16 H,Int16 *w,Int16 *h,KNOTT *ptrc,FRAME **frm,
217
Float32 Max_koof_for_width,Float32 Max_koof_for_height);
218
Int16 GetOffsetVerticalCell(Int16 L,Int16 H,Int16 *w,Int16 *h,KNOTT *ptrc,FRAME **frm);
201
int16_t SortHorLine1(LINE_KNOT *LineHK,int16_t NumH,LINE_KNOT *LineVK,int16_t NumV,
202
KNOTT *Root,KNOTT ***colt1,int16_t *k_colt1,FRAME **frm);
203
char *get2_param(char *str,char *param,int16_t max_len);
204
int16_t Check_IsItFalseHorLine(int16_t recalc,int16_t reg,FRAME **frm,int16_t *his,int16_t pos,int16_t len,
205
int16_t maxh,int16_t sum,int16_t len_group,int16_t *his_first_group,
206
int16_t *his_second_group,BOUND *bnd,int16_t k_frm);
207
int16_t check_white_int(int16_t beg_white_int,int16_t end_white_int,int16_t maxh,
208
int16_t *his_second_group);
209
int16_t GetRealSize( char* str,int16_t len,int16_t FontSize ,int16_t FontNumber,int16_t* strHeight);
210
void Get_all_term_fragms( KNOTT *ptr,int16_t *Colt,int16_t *iv ,int16_t NumCol,FRAME **frm);
211
void Get_all_term_fragms1( KNOTT* ptr,int16_t* Colt,int16_t* iv,int16_t NumCol,FRAME **frm);
212
int16_t term_col_seriated(int16_t* term_ind,int16_t Count_Term_Col,int16_t* K_Ver_Flag_Term);
213
int16_t OrderingAndRecalcCol(int16_t Nsector,int16_t Ncol,int16_t H0,int16_t L0,int16_t *W_P,int16_t *H_P,
214
int16_t dist_col,KNOTT *pRoot,FRAME **frm,
215
float Max_koof_for_width,float Max_koof_for_height);
216
int16_t RecalcRect(int16_t L,int16_t H,int16_t *w,int16_t *h,KNOTT *ptrc,FRAME **frm,
217
float Max_koof_for_width,float Max_koof_for_height);
218
int16_t GetOffsetVerticalCell(int16_t L,int16_t H,int16_t *w,int16_t *h,KNOTT *ptrc,FRAME **frm);
219
219
void RtfUnionRect_CRect_SRect(tagRECT *s1,SRECT *s2);
220
220
void RtfUnionRect_CRect_CRect(tagRECT *s1,tagRECT *s2);
221
221
void RtfAssignRect_CRect_SRect(tagRECT *s1,SRECT *s2);
570
static Int16 Realloc2(KNOTT*** colt,KNOTT*** colnt,KNOTT*** colnt1,
571
Int16 **begI,Int16 **endI,Int16 **intr,Int16 nOld,Int16 nNew)
572
{ Int16 oldS =nOld*sizeof(PTR),newS =nNew*sizeof(PTR),
573
oldS1=nOld*sizeof(Int16),newS1=nNew*sizeof(Int16);
570
static int16_t Realloc2(KNOTT*** colt,KNOTT*** colnt,KNOTT*** colnt1,
571
int16_t **begI,int16_t **endI,int16_t **intr,int16_t nOld,int16_t nNew)
572
{ int16_t oldS =nOld*sizeof(PTR),newS =nNew*sizeof(PTR),
573
oldS1=nOld*sizeof(int16_t),newS1=nNew*sizeof(int16_t);
574
574
if((colt && ((*colt=(KNOTT**)realloc_m(*colt, oldS,newS))==NULL))||
575
575
(colnt && ((*colnt=(KNOTT**)realloc_m(*colnt, oldS,newS))==NULL))||
576
576
(colnt1 && ((*colnt1=(KNOTT**)realloc_m(*colnt1,oldS,newS))==NULL))||
577
(begI && ((*begI=(Int16*)realloc_m(*begI,oldS1,newS1))==NULL))||
578
(endI && ((*endI=(Int16*)realloc_m(*endI,oldS1,newS1))==NULL))||
579
(intr && ((*intr=(Int16*)realloc_m(*intr,oldS1,newS1))==NULL)))
577
(begI && ((*begI=(int16_t*)realloc_m(*begI,oldS1,newS1))==NULL))||
578
(endI && ((*endI=(int16_t*)realloc_m(*endI,oldS1,newS1))==NULL))||
579
(intr && ((*intr=(int16_t*)realloc_m(*intr,oldS1,newS1))==NULL)))
580
580
return NOT_ALLOC;
645
645
//--calling internal function for tree generation--
646
646
if(CreateTreePlainTxt1(BndAll,NULL,0,NULL,0,
647
647
frm,NumFragm,Inf, setup->size_x, setup->size_y))
648
return (Int16)fl-200;
648
return (int16_t)fl-200;
653
//������� ������ ���-�� Text Plain
653
//Создать дерево стр-ры Text Plain
655
655
// BndTxt - page boundaries
656
// LineV[NumLV],LineH[NumLH] - ������������ � �������������� �����, ��������� �� �����
657
// frm[NumFrm] - ����� ���� (���������� � CunieForm) �����
658
// size_x,size_y - ��������. ������ ���� �����
656
// LineV[NumLV],LineH[NumLH] - вертикальные и горизонтальные линии, найденные на листе
657
// frm[NumFrm] - рамки букв (фрагментов в CunieForm) листа
658
// size_x,size_y - стандарт. размер букв листа
660
// Inf - �������������� ��������� �������� ������ ������� �����
660
// Inf - результирующая структура хранения дерева колонок листа
663
Int16 CreateTreePlainTxt1(BOUND BndTxt,STRET *LineV,Int16 NumLV,STRET *LineH,
664
Int16 NumLH,FRAME **frm,Int16 NumFrm,INF_TREE *Inf,Int16 size_x,Int16 size_y)
663
int16_t CreateTreePlainTxt1(BOUND BndTxt,STRET *LineV,int16_t NumLV,STRET *LineH,
664
int16_t NumLH,FRAME **frm,int16_t NumFrm,INF_TREE *Inf,int16_t size_x,int16_t size_y)
667
Int16 i,nVmax=3*MAX_COL,nHmax=3*MAX_COL,nV,nH,j;
668
Int16 nT=nVmax+1,fl,tmp,InBegFrm,NumF,ThresX,ThresY;
669
Int16 left,right,top,bottom,NumMax=3*MAX_COL,MaxOld;
670
Int16 *intr,*begI,*endI,NumT=nVmax+1;
671
Int16 k_colnt,k_colnt1,k_colt,minz;
672
Int16 fl_beg/*������� ������� ����������� �� �������*/;
673
Int16 order/*��� ������� ���������������:HOR - ��������. ��� VER - ��������.*/;
674
Int16 kf,kcol,del,del1;
667
int16_t i,nVmax=3*MAX_COL,nHmax=3*MAX_COL,nV,nH,j;
668
int16_t nT=nVmax+1,fl,tmp,InBegFrm,NumF,ThresX,ThresY;
669
int16_t left,right,top,bottom,NumMax=3*MAX_COL,MaxOld;
670
int16_t *intr,*begI,*endI,NumT=nVmax+1;
671
int16_t k_colnt,k_colnt1,k_colt,minz;
672
int16_t fl_beg/*Признак первого расщепления на колонки*/;
673
int16_t order/*Тип искомой упорядоченности:HOR - горизонт. или VER - вертикал.*/;
674
int16_t kf,kcol,del,del1;
677
677
KNOTT *PrevChild,*Child;
724
724
FillFieldKNOTT1(Tree.Root,0,1,0,1,0,NumFrm,IN_NO,UNSORT,ROOT,TRUE,ALG_BEG,ALG_BEG,NULL);
725
725
colnt[k_colnt=0]=Tree.Root; k_colt=-1;
726
fl_beg=1; order=VER;//��� ������� ��� RTF-converter
727
ThresX=ThresY=(Int16)(1.5*size_y);
726
fl_beg=1; order=VER;//Так удобнее для RTF-converter
727
ThresX=ThresY=(int16_t)(1.5*size_y);
729
Int16 MaxAllowLev,flTerm;
729
int16_t MaxAllowLev,flTerm;
731
731
MaxLev=0; flTerm=FALSE;
733
//������� �������, ��� ��� ��������� �������� ���� �������,
734
//������� ���� ����������� - �� ������ �������� MaxLev �����������
735
//������� ��������� �� ����-�������, ������� ���� �� ���� ������
736
//� ��� ��� �����-�������, ������� ����������, ������ ��������
737
//����-���������� �� ��������� ������ MaxLev+1
738
//colnt[k_colnt] - ������ ����� �������� ������ MaxLev
739
//colnt1[k_colnt1] - ������ ����� ���������� ������ MaxLev+1
740
//colt[k_colt] - ������ ������������ �������
741
//������� ����� �������� - �� ��������� ������ ��� �����, �.�. �� ����
742
//�� ����� ����������� ������ �� ������� ����������
733
//вначале считаем, что все фрагменты образуют одну колонку,
734
//внешний цикл колонизации - на каждой итерации MaxLev производитс
735
//попытка разделить те узлы-колонки, которые есть на этом уровне
736
//и для тех узлов-колонок, которые поделились, строим дочерние
737
//узлы-подколонки на следующем уровне MaxLev+1
738
//colnt[k_colnt] - массив узлов текущего уровня MaxLev
739
//colnt1[k_colnt1] - массив узлов следующего уровня MaxLev+1
740
//colt[k_colt] - массив терминальных колонок
741
//признак конца итераций - на очередном уровне нет узлов, т.е. ни один
742
//из узлов предыдущего уровня не удалось раздробить
744
744
while(k_colnt >= 0)
746
if(++MaxLev > MaxAllowLev) //����������� Word-a �� ������� ������
746
if(++MaxLev > MaxAllowLev) //ограничение Word-a на глубину дерева
749
k_colnt1=-1; /*����� ����������. ������� ����. ������*/
750
//--���� ������� ��������� ���� ����� �������� ������--
749
k_colnt1=-1; /*Число нетерминал. колонок след. уровня*/
750
//--цикл попытки дробления всех узлов текущего уровня--
751
751
CONS_MESS1("while.................... k_colnt=%d ",k_colnt);
755
755
CONS_MESS1("beg......................1 ");
756
756
CONS_MESS1("i=%d ",i);
757
ptr=colnt[i]; //������� ����
758
left=ptr->InBegFrm; //������ ������ ����� (���������) ����
759
kf=ptr->NumFrm-1; //����� �����(����������)����
760
ptr->OrderChild=UNSORT;//������� �������, ��� ����� ���� �������������
761
//���� �� ���� ������� �������, �� �������
762
//���� ������������ ���������������� ��� ��������
763
//����� (V- ��� H-�������)
757
ptr=colnt[i]; //текущий узел
758
left=ptr->InBegFrm; //индекс первой рамки (фрагмента) узла
759
kf=ptr->NumFrm-1; //число рамок(фрагментов)узла
760
ptr->OrderChild=UNSORT;//вначале считаем, что рамки узла неупорядочены
761
//если же узел удастся разбить, то порядок
762
//узла определяется упорядоченностью его дочерних
763
//узлов (V- или H-порядок)
764
764
CONS_MESS1("(index first fragm)left=%d , (count fragm) kf=%d ",left,kf);
767
bound_frm(&frm[left],kf,&bndc); //����� ���� ���� ����� �������� � ���� ����� ����������
767
bound_frm(&frm[left],kf,&bndc); //рамка узла есть рамка входящих в узел рамок фрагментов
769
bndc=BndTxt; //������� ����� ����-����� ���� ����� ����� �����
769
bndc=BndTxt; //вначале рамка узла-корня есть рамка всего листа
770
770
CONS_MESS1("fl_beg=%d, bndc : left=%d, right=%d, up=%d, down=%d",fl_beg,bndc.left,bndc.right,bndc.up,bndc.down);
773
//-- ������� ��������� ���� ����� ���������� ���������������� --
774
// �������: �� ��� Ox ��� order=HOR ��� �� ��� Oy ��� order=VER
775
// � ������ �� ��� ����������� �������
773
//-- попытка разбиение узла путем построения соответствующего --
774
// профиля: на ось Ox для order=HOR или на ось Oy для order=VER
775
// и поиска на нем межколонных зазоров
986
//��������� ���� ������ ���� �������
987
//!!! ���� left,right,top,bottom ����� ����� �������� ����� ���������
986
//заполняем поля нового узла колонки
987
//!!! поля left,right,top,bottom имеют смысл индексов линий разграфки
988
988
FillFieldKNOTT1(Child,left,right,top,bottom,
989
989
InBegFrm,NumF,IN_NO,UNSORT,CELL,TRUE,ALG_BEG,ALG_BEG,NULL);
992
992
if(++k_colnt1 >= NumMax)
995
NumMax=(Int16)(NumMax*1.5);
995
NumMax=(int16_t)(NumMax*1.5);
996
996
if(Realloc2(&colt,&colnt,&colnt1,&begI,&endI,&intr,old,NumMax) == NOT_ALLOC)
998
998
CONS_MESS9("976 NOT_ALLOC");
999
999
return NOT_ALLOC;
1002
colnt1[k_colnt1]=Child;//���������� ��������� ����������. �������
1002
colnt1[k_colnt1]=Child;//Запоминаем очередную нетерминал. колонку
1004
1004
PrevChild=Child;
1005
1005
CONS_MESS1("end------------------3");
1007
1007
CONS_MESS1("end------------------2");
1009
else /*���������� ��������. �������*/
1009
else /*Обнаружена терминал. колонка*/
1011
CONS_MESS1("���������� ��������. �������");
1011
CONS_MESS1("Обнаружена терминал. колонка");
1012
1012
CONS_MESS1("beg------------------2.1");
1013
1013
if(++k_colt >= NumMax)
1016
NumMax=(Int16)(NumMax*1.5);
1016
NumMax=(int16_t)(NumMax*1.5);
1017
1017
if(Realloc2(&colt,&colnt,&colnt1,&begI,&endI,&intr,old,NumMax)
1135
/*������������� ����� �� �������� ����� ���������� ��������� �����������
1136
�������� ������������� ��������
1137
����: frm[k_frm] - ����� ��������� (����������);
1138
bnd - �������� �������� ����;
1139
ave_x,ave_y - ������� ��������� ����� ����������;
1140
NumMax - ��������.����� �������
1141
�����:frm[k_frm] - ����� ��������������� ���������, ���� ������� ����������;
1142
intr1[kcol] - ������ ������� ��������� ������� � ������� frm,
1143
begI,endI - �������������� ������� ��������. ����������
1135
/*Классификация рамок по колонкам после устранения перекосов рекурсивным
1136
делением ортогональных профилей
1137
Вход: frm[k_frm] - рамки компонент (фрагментов);
1138
bnd - габариты текущего узла;
1139
ave_x,ave_y - среднее габаритов рамки компоненты;
1140
NumMax - максимал.число колонок
1141
Выход:frm[k_frm] - рамки переупорядочены поколонно, если колонки обнаружены;
1142
intr1[kcol] - правые границы найденных колонок в массиве frm,
1143
begI,endI - геометрические границы межколон. интервалов
1145
0 - ���� ������� �� ����������,
1146
kcol, ���� ����������,
1145
0 - если колонки не обнаружены,
1146
kcol, если обнаружены,
1150
Int16 SearchColHist1(FRAME **frm,Int16 k_frm,BOUND *bnd,Int16 ave_x,Int16 ave_y,
1151
Int16 reg,Int16 *k_int,Int16 **intr1,Int16 **begI,Int16 **endI,Int16 *NumMax)
1150
int16_t SearchColHist1(FRAME **frm,int16_t k_frm,BOUND *bnd,int16_t ave_x,int16_t ave_y,
1151
int16_t reg,int16_t *k_int,int16_t **intr1,int16_t **begI,int16_t **endI,int16_t *NumMax)
1154
Int16 ave_dir,ave_ort,i,kcol,x,in,kf,fl,ki,MaxOld=*NumMax;
1154
int16_t ave_dir,ave_ort,i,kcol,x,in,kf,fl,ki,MaxOld=*NumMax;
1156
int16_t *intr=*intr1;
1157
1157
KNOT4 *Free,**knot,**beg=(KNOT4**)malloc(*NumMax*sizeof(PTR)),*ptr;
1159
1159
CONS_MESS3("===beg SearchColHist1 ===");
1235
/*����� ������� �� ��������� ���� ����������� - ������� ��������� ������ ����
1236
������� ������� ������
1237
����: frm[k_frm] - ����� ��������� (����������);
1238
bnd - �������� �������� ����;
1239
ave_dir,ave_ort - ������� ������� �����-���������� � ������ � ���������������� ����.
1240
NumMax - ��������.����� �������
1241
reg - ����� ����������� (HOR - �������������-������������� �������,
1242
VER - ����������� --//--).
1243
�����:frm[k_frm] - ����� ��������������� ���������, ���� ������� ����������;
1244
intr1[kcol] - ������ ������� ��������� ������� � ������� frm,
1245
beg1,end1 - [k_int1] �������������� ������� ��������. ����������
1246
�����:intr[k_int1]-�������� ��������� ����������� ����������
1247
reg=HOR - ���� ��������. ������������� �������,VER - �����������-�������������
1235
/*Поиск колонок по вертикали либо горизонтали - функция разбиения одного узла
1236
методом анализа профил
1237
Вход: frm[k_frm] - рамки компонент (фрагментов);
1238
bnd - габариты текущего узла;
1239
ave_dir,ave_ort - среднее размера буквы-компоненты в прямом и перпендикулярном напр.
1240
NumMax - максимал.число колонок
1241
reg - режим колонизации (HOR - горизонтально-упорядоченные колонки,
1242
VER - вертикально --//--).
1243
Выход:frm[k_frm] - рамки переупорядочены поколонно, если колонки обнаружены;
1244
intr1[kcol] - правые границы найденных колонок в массиве frm,
1245
beg1,end1 - [k_int1] геометрические границы межколон. интервалов
1246
Выход:intr[k_int1]-середины найденных межколонных интервалов
1247
reg=HOR - ищем горизонт. упорядоченные колонки,VER - вертикально-упорядоченные
1249
0 - ��������� �� ���������,
1250
1 - ��������� ���������,
1249
0 - разбиение не произошло,
1250
1 - разбиение произошло,
1254
Int16 SearchInterval1(FRAME **frm,Int16 k_frm,Int16 **beg1,Int16 **end1,
1255
Int16 *k_int1,BOUND *bnd,Int16 ave_dir,Int16 ave_ort,Int16 reg,Int16 *NumMax)
1254
int16_t SearchInterval1(FRAME **frm,int16_t k_frm,int16_t **beg1,int16_t **end1,
1255
int16_t *k_int1,BOUND *bnd,int16_t ave_dir,int16_t ave_ort,int16_t reg,int16_t *NumMax)
1258
Int16 k_int,pos,min_col,min_int,maxh,minh,midh,kstr,len,len_group,i,j;
1259
Int16 beg_int,end_int,sumh,ave_h,mi,ma,Home,Fin;
1260
Int16 *his,*his_first_group,*his_second_group,last_real_line,
1258
int16_t k_int,pos,min_col,min_int,maxh,minh,midh,kstr,len,len_group,i,j;
1259
int16_t beg_int,end_int,sumh,ave_h,mi,ma,Home,Fin;
1260
int16_t *his,*his_first_group,*his_second_group,last_real_line,
1261
1261
*Beg=*beg1,*End=*end1,tmp_pos;
1263
//--������ ���������� ���������� �����������--
1264
min_col=1;//�����. ����� ������� � ��������
1265
min_int=ave_dir*2;//�����. ����� ��������� � ��������
1266
maxh =0;//����.���������� ������ ����������� � ���������-�������� �������.������ ���������
1267
midh =0;//����.���������� ������� ������ ����-�� � ���������
1268
minh =1;//���.���������� ������ ����������� � �������-�������� �������.������ �������
1269
//����� ���������� ��������� � � ������ ���� �����
1263
//--Расчет параметров одномерной колонизации--
1264
min_col=1;//миним. длина колонки в пикселах
1265
min_int=ave_dir*2;//миним. длина интервала в пикселах
1266
maxh =0;//Макс.допустимая высота гистограммы в интервале-критерий обнаруж.начала интервала
1267
midh =0;//Макс.допустимая средняя высота гист-мы в интервале
1268
minh =1;//Мин.допустимая высота гистограммы в колонке-критерий обнаруж.начала колонки
1269
//после настоящего интервала и с левого края листа
1272
1272
min_int=5;/*ave_dir * 1.5*/; //~~~
1660
New=(KNOTT*)inc_lst((KNOT**)&New,(KNOT**)free);//������
1660
New=(KNOTT*)inc_lst((KNOT**)&New,(KNOT**)free);//корень
1662
1662
New->up=up; New->down=NULL;
1665
//===���������� ����� ���� KNOTT ���������. ������ TREE2
1666
void FillFieldKNOTT1(KNOTT *ptr,Int16 Left,Int16 Right,Int16 Top,Int16 Bottom,
1667
Int16 InBegFrm,Int16 NumFrm,Int16 InColA,
1665
//===Заполнение полей узла KNOTT ортогонал. дерева TREE2
1666
void FillFieldKNOTT1(KNOTT *ptr,int16_t Left,int16_t Right,int16_t Top,int16_t Bottom,
1667
int16_t InBegFrm,int16_t NumFrm,int16_t InColA,
1668
1668
uint OrderChild,uint Type,uint AllowOCR,uint JustH,uint JustV,char *Name)
1671
ptr->Rect.top=Top; //������ ����� - ������� �������
1672
ptr->Rect.bottom=Bottom; //--/-- ������
1673
ptr->Rect.left=Left; //--/-- �����
1674
ptr->Rect.right=Right; //--/-- ������
1675
ptr->InBegFrm=InBegFrm; //������ �����. ��������� �������
1676
ptr->NumFrm=NumFrm; //����� ���������� ������� (��������� ����� ������� ���� � ������� frm ������)
1677
ptr->InColA=InColA; //������ ������� ��������� ������ �������
1678
ptr->OrderChild=OrderChild; //������� ������� ����
1671
ptr->Rect.top=Top; //индекс линии - верхней границы
1672
ptr->Rect.bottom=Bottom; //--/-- нижней
1673
ptr->Rect.left=Left; //--/-- левой
1674
ptr->Rect.right=Right; //--/-- правой
1675
ptr->InBegFrm=InBegFrm; //индекс начал. фрагмента колонки
1676
ptr->NumFrm=NumFrm; //число фрагментов колонки (фрагменты одной колонки идут в массиве frm подряд)
1677
ptr->InColA=InColA; //индекс первого фрагмента данной колонки
1678
ptr->OrderChild=OrderChild; //порядок дочерей узла
1679
1679
ptr->Type=Type; //
1680
1680
ptr->AllowOCR=AllowOCR; //
1681
1681
ptr->JustH=JustH; //
1684
1684
ptr->RefOrt=ptr->RefH=NULL; //
1687
Int16 compINDEX_SORT1(INDEX_SORT *a,INDEX_SORT *b)
1687
int16_t compINDEX_SORT1(INDEX_SORT *a,INDEX_SORT *b)
1689
1689
{return (a->value >= b->value ? 1:-1);}
1691
Int16 compLINE_KNOT1(LINE_KNOT *a,LINE_KNOT *b)
1691
int16_t compLINE_KNOT1(LINE_KNOT *a,LINE_KNOT *b)
1693
1693
{return (a->beg >= b->beg ? 1:-1);}
1694
//���������� H-����� ������ �� ���������
1695
//� �������� ���������� ������� ��������. V-������� (k_colt1 - ������)
1696
//���� V-����� �� �����������, ��� ����� ����������
1694
//сортировка H-линий дерева по вертикали
1695
//и попутное заполнение массива терминал. V-колонок (k_colt1 - индекс)
1696
//если V-линии не упорядочены, они также сортируютс
1698
Int16 SortHorLine1(LINE_KNOT *LineHK,Int16 NumH,LINE_KNOT *LineVK,Int16 NumV,
1699
KNOTT *Root,KNOTT ***colt1,Int16 *k_colt1,FRAME **frm)
1698
int16_t SortHorLine1(LINE_KNOT *LineHK,int16_t NumH,LINE_KNOT *LineVK,int16_t NumV,
1699
KNOTT *Root,KNOTT ***colt1,int16_t *k_colt1,FRAME **frm)
1702
1702
INDEX_SORT *Ind=(INDEX_SORT *)malloc(MAX(NumH,NumV)*sizeof(INDEX_SORT));
1703
1703
STAT_CELL StDefault;
1704
Int16 *Index=(Int16 *)malloc(NumH*sizeof(Int16)),
1705
*IndexV=(Int16 *)malloc(NumV*sizeof(Int16));
1706
Int16 i,DepthTree=20,flV;
1704
int16_t *Index=(int16_t *)malloc(NumH*sizeof(int16_t)),
1705
*IndexV=(int16_t *)malloc(NumV*sizeof(int16_t));
1706
int16_t i,DepthTree=20,flV;
1708
1708
KNOTT *Curr,**colt;
1711
1711
StDefault.dyLow=NORM_SCAN(20);
1712
//--���������� H-�����--
1712
//--сортировка H-линий--
1713
1713
for(i=0; i < NumH; ++i) {Ind[i].ind=i;Ind[i].value=LineHK[i].beg;}
1714
1714
u4sort(Ind,NumH,sizeof(INDEX_SORT),(COMP_FUN)compINDEX_SORT1);
1715
1715
u4sort(LineHK,NumH,sizeof(LINE_KNOT),(COMP_FUN)compLINE_KNOT1);
1716
1716
for(i=0; i < NumH; ++i) Index[Ind[i].ind]=i;
1717
//--���������� V-�����--
1717
//--сортировка V-линий--
1719
1719
for(i=0; i < NumV; ++i)
1720
1720
{ Ind[i].ind=i;Ind[i].value=LineVK[i].beg;
1721
1721
if(i && LineVK[i-1].beg > LineVK[i].beg) flV=1;
1723
if(flV)//V-����� �������������
1723
if(flV)//V-линии неупорядочены
1724
1724
{ u4sort(Ind,NumV,sizeof(INDEX_SORT),(COMP_FUN)compINDEX_SORT1);
1725
1725
u4sort(LineVK,NumV,sizeof(LINE_KNOT),(COMP_FUN)compLINE_KNOT1);
1727
1727
for(i=0; i < NumV; ++i) IndexV[Ind[i].ind]=i;
1729
if(NewStack(DepthTree,&St)) //������� ���� ��� ������ ������
1729
if(NewStack(DepthTree,&St)) //создать стек для обхода дерева
1730
1730
return NOT_ALLOC;
1732
1732
Curr=Root; k_colt=0;
1733
while(Curr != NULL)//I ������ TREE-������������� H-����� � ������ ����� TERM Cell
1733
while(Curr != NULL)//I проход TREE-перенумерация H-линий и расчет числа TERM Cell
1735
1735
Curr->Rect.top=Index[Curr->Rect.top];
1736
1736
Curr->Rect.bottom=Index[Curr->Rect.bottom];
1815
// ����� ������ USE_FRAME_AND_COLUMN
1816
//=========��������� �������� �� �������
1817
// ������� �� �������������� �������
1818
// �������������� ������� �� ������������ �������
1819
// ����������� �������������� ������������ �������
1820
// ����������� RtfPage.
1821
BOOL PageTree( FILE *InFileName, CRtfPage* RtfPage, const char* OutFileName)
1815
// Режим работы USE_FRAME_AND_COLUMN
1816
//=========Разбиение страницы на сектора
1817
// Секторы на горизантальные колонки
1818
// Горизантальные колонки на вертикальные колонки
1819
// Определение терминальности вертикальных колонок
1820
// Запольнение RtfPage.
1821
Bool PageTree( FILE *InFileName, CRtfPage* RtfPage, const char* OutFileName)
1823
Int16 nc,ns,nw,nz,fl,i,i_ns1,i_nsb,i_nse,j,ih,iv,iv1,kp,kp1,kp2,
1823
int16_t nc,ns,nw,nz,fl,i,i_ns1,i_nsb,i_nse,j,ih,iv,iv1,kp,kp1,kp2,
1824
1824
n_beg,dist_hor_col=240,dist_sec=360,flag_vse_term=1,OldNumCol;
1825
Int16 FlagBadColumn;
1825
int16_t FlagBadColumn;
1826
1826
const char *err="PageTree";
1828
Int16 ***Colt,K_Sect,*K_Hor,**K_Ver_Flag_Term,**K_Ver_Add_On,**K_Ver_Offset,**K_Ver;
1828
int16_t ***Colt,K_Sect,*K_Hor,**K_Ver_Flag_Term,**K_Ver_Add_On,**K_Ver_Offset,**K_Ver;
1829
1829
COLH **ColH,**ColH_New;
1832
BOOL FlagBadBad = FALSE;
1832
Bool FlagBadBad = FALSE;
1833
1833
KNOTT *RootUdal=NULL;
2024
//converter from Inf, ��� ����� ������, � ������������� WORD-�����
2025
//������������� �������� �������:
2024
//converter from Inf, где лежит дерево, в трехуровневую uint16_t-схему
2025
//представления иерархии колонок:
2027
2027
// K_Hor[K_Sect]
2028
2028
// K_Ver[K_Sect][K_Hor[K_Sect]]
2029
// K_Ver_Flag_Term ��������� �������� ������� :
2030
// 0----������� �������; 1----������� ������� c ����. �����������; 2----- ������� �������
2029
// K_Ver_Flag_Term указывает свойства колонки :
2030
// 0----простая колонка; 1----простая колонка c терм. фрагментами; 2----- сложная колонка
2032
2032
k_col[1]=CalcNumDau(pRoot)-1;
2033
/***************** �����. ������� - �������. *********************************/
2033
/***************** Начал. порядок - горизон. *********************************/
2034
2034
if(pRoot->OrderChild == HOR)
2036
CONS_MESS4("�����. ������� - �������.");
2037
CONS_MESS4("���������� ����� =%d",k_col[1]+1);
2036
CONS_MESS4("Начал. порядок - горизон.");
2037
CONS_MESS4("Количество колон =%d",k_col[1]+1);
2040
K_Hor=(Int16*)malloc((K_Sect+1)*sizeof(Int16));
2040
K_Hor=(int16_t*)malloc((K_Sect+1)*sizeof(int16_t));
2041
2041
K_Hor[0]=k_col[1];
2042
K_Ver=(Int16**)malloc((K_Sect+1)*sizeof(Int16*));
2043
K_Ver_Flag_Term=(Int16**)malloc((K_Sect+1)*sizeof(Int16*));
2044
Colt=(Int16***)malloc((K_Sect+1)*sizeof(Int16**));
2042
K_Ver=(int16_t**)malloc((K_Sect+1)*sizeof(int16_t*));
2043
K_Ver_Flag_Term=(int16_t**)malloc((K_Sect+1)*sizeof(int16_t*));
2044
Colt=(int16_t***)malloc((K_Sect+1)*sizeof(int16_t**));
2045
2045
if(K_Hor==NULL||K_Ver_Flag_Term==NULL||K_Ver==NULL||Colt==NULL)
2046
2046
return NOT_ALLOC;
2047
if((K_Ver[0]=(Int16*) malloc((K_Hor[0]+1)*sizeof(Int16)))==NULL||
2048
(K_Ver_Flag_Term[0]=(Int16*) malloc((K_Hor[0]+1)*sizeof(Int16)))==NULL||
2049
(Colt [0]=(Int16**)malloc((K_Hor[0]+1)*sizeof(PTR)))==NULL)
2047
if((K_Ver[0]=(int16_t*) malloc((K_Hor[0]+1)*sizeof(int16_t)))==NULL||
2048
(K_Ver_Flag_Term[0]=(int16_t*) malloc((K_Hor[0]+1)*sizeof(int16_t)))==NULL||
2049
(Colt [0]=(int16_t**)malloc((K_Hor[0]+1)*sizeof(PTR)))==NULL)
2050
2050
return NOT_ALLOC;
2052
2052
for(ih=0,ptr=pRoot->down; ih <= K_Hor[0]; ++ih,ptr=ptr->next)
2117
2117
K_Ver[0][ih] = --iv;
2119
if(det4 && dets) ConsMess("���-�� ����. �������=%d",K_Ver[0][ih]+1);
2119
if(det4 && dets) ConsMess("Кол-во терм. колонок=%d",K_Ver[0][ih]+1);
2125
if(!K_Ver_Flag_Term[0][ih]) ConsMess("������� �������");
2125
if(!K_Ver_Flag_Term[0][ih]) ConsMess("Колонка простая");
2127
if(det4 && K_Ver_Flag_Term[0][ih]==1) ConsMess("������� ������� � ������� �� ����.����-���");
2128
else ConsMess("������� ������� ��������� (������) ");
2127
if(det4 && K_Ver_Flag_Term[0][ih]==1) ConsMess("Колонка простая и состоит из терм.фраг-тов");
2128
else ConsMess("Колонка сложной структуры (фреймы) ");
2133
/***************** �����. ������� - ��������. *********************************/
2133
/***************** Начал. порядок - вертикал. *********************************/
2135
2135
if(pRoot->OrderChild == VER)
2137
CONS_MESS4("�����. ������� - ��������.");
2138
CONS_MESS4("���������� ������ =%d",k_col[1]+1);
2137
CONS_MESS4("Начал. порядок - вертикал.");
2138
CONS_MESS4("Количество секций =%d",k_col[1]+1);
2140
2140
K_Sect=k_col[1];
2141
K_Hor=(Int16*)malloc((K_Sect+1)*sizeof(Int16));
2142
K_Ver=(Int16**)malloc((K_Sect+1)*sizeof(Int16*));
2143
K_Ver_Flag_Term=(Int16**)malloc((K_Sect+1)*sizeof(Int16*));
2144
Colt =(Int16***)malloc((K_Sect+1)*sizeof(Int16**));
2141
K_Hor=(int16_t*)malloc((K_Sect+1)*sizeof(int16_t));
2142
K_Ver=(int16_t**)malloc((K_Sect+1)*sizeof(int16_t*));
2143
K_Ver_Flag_Term=(int16_t**)malloc((K_Sect+1)*sizeof(int16_t*));
2144
Colt =(int16_t***)malloc((K_Sect+1)*sizeof(int16_t**));
2145
2145
if(K_Hor==NULL||K_Ver_Flag_Term==NULL||K_Ver==NULL||Colt==NULL)
2146
2146
return NOT_ALLOC;
2147
//****** ���� �� �������,������ ������ - �� 2-��������� �������� ***********
2147
//****** Цикл по секциям,внутри каждой - до 2-уровневой иерархии ***********
2148
2148
for(i=0,ptr=pRoot->down; i <= K_Sect; ++i,ptr=ptr->next)
2150
2150
kp=CalcNumDau(ptr)-1;
2151
CONS_MESS4("***������ #%d- �� %d �����. ������� ",i+1,kp<0?1:kp+1);
2151
CONS_MESS4("***Секция #%d- из %d гориз. колонок ",i+1,kp<0?1:kp+1);
2153
//������ - ���� ��������. �������
2153
//Секция - одна терминал. колонка
2157
K_Ver[i]=(Int16*)malloc((K_Hor[i]+1)*sizeof(Int16));
2158
K_Ver_Flag_Term[i]=(Int16*)malloc((K_Hor[i]+1)*sizeof(Int16));
2159
Colt[i] =(Int16**)malloc((K_Hor[i]+1)*sizeof(Int16*));
2157
K_Ver[i]=(int16_t*)malloc((K_Hor[i]+1)*sizeof(int16_t));
2158
K_Ver_Flag_Term[i]=(int16_t*)malloc((K_Hor[i]+1)*sizeof(int16_t));
2159
Colt[i] =(int16_t**)malloc((K_Hor[i]+1)*sizeof(int16_t*));
2160
2160
if(K_Ver[i]==NULL||K_Ver_Flag_Term[i]==NULL||Colt[i]==NULL)
2161
2161
return NOT_ALLOC;
2739
void Get_all_term_fragms( KNOTT* ptr,Int16* Colt,Int16* iv,Int16 NumCol,FRAME **frm)
2739
void Get_all_term_fragms( KNOTT* ptr,int16_t* Colt,int16_t* iv,int16_t NumCol,FRAME **frm)
2741
Int16 i,i1,i2,i3,kp,kp1,kp2,kp3,kp4;
2741
int16_t i,i1,i2,i3,kp,kp1,kp2,kp3,kp4;
2742
2742
KNOTT *ptr1,*ptr2,*ptr3,*ptr4;
2744
2744
kp=CalcNumDau(ptr)-1;
2745
2745
for(i=0,ptr1=ptr->down; i <= kp; ++i,ptr1=ptr1->next)
2747
kp1=CalcNumDau(ptr1)-1;//����� ������� col
2748
if(kp1 < 0) //����. col
2747
kp1=CalcNumDau(ptr1)-1;//Число дочерей col
2748
if(kp1 < 0) //Терм. col
2749
2749
Get_all_term_fragms1( ptr1, Colt, iv, NumCol,frm);
2752
2752
for(i1=0,ptr2=ptr1->down; i1 <= kp1; ++i1,ptr2=ptr2->next)
2754
2754
kp2=CalcNumDau(ptr2)-1;
2755
if(kp2 < 0) //����. col
2755
if(kp2 < 0) //Терм. col
2756
2756
Get_all_term_fragms1( ptr2, Colt, iv, NumCol,frm);
2759
2759
for(i2=0,ptr3=ptr2->down; i2 <= kp2; ++i2,ptr3=ptr3->next)
2761
2761
kp3=CalcNumDau(ptr3)-1;
2762
if(kp3 < 0) //����. col
2762
if(kp3 < 0) //Терм. col
2763
2763
Get_all_term_fragms1( ptr3, Colt, iv, NumCol,frm);
2766
2766
for(i3=0,ptr4=ptr3->down; i3 <= kp3; ++i3,ptr4=ptr4->next)
2768
2768
kp4=CalcNumDau(ptr4)-1;
2769
if(kp4 < 0) //����. col
2769
if(kp4 < 0) //Терм. col
2770
2770
Get_all_term_fragms1( ptr4, Colt, iv, NumCol,frm);
2773
if(det11) ConsMess(" ������ !!! ");
2773
if(det11) ConsMess(" Ошибка !!! ");