~ubuntu-branches/ubuntu/trusty/cuneiform/trusty

« back to all changes in this revision

Viewing changes to cuneiform_src/Kern/fon/src/distance.c

  • Committer: Bazaar Package Importer
  • Author(s): Jakub Wilk, c-assert.diff, slovenian-slv.diff
  • Date: 2011-01-26 21:53:07 UTC
  • mfrom: (5.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20110126215307-62x61mcesr607qb7
Tags: 1.0.0+dfsg-2
* Upload to unstable.
* Explicitly build-depend on pkg-config. Thanks to Stefano Rivera for the
  bug report.
* Add Vcs-* fields.
* Use the standard C assert() macro, rather than custom Cuneiform one.
  [c-assert.diff]
* Pass CFLAGS, CXXFLAGS and LDFLAGS (get from dpkg-buildflags) to cmake
  (closes: #608345). Thanks to Sami Liedes for the bug report.
  + Build depend on dpkg-dev (>= 1.15.7).
* Pass --parallel to dh.
  + Bump debhelper minimum version to 7.4.10.
* Update debian/copyright to the latest DEP-5 version.
* Bump year in debian/copyright.
* Explicitly link to GraphicsMagick (rather than via the ImageMagick
  compatibility layer).
* Don't ship /usr/lib/cuneiform/*.so symlinks. These libraries are
  considered private, at least until #598616 is fixed.
* Rename some private variables in debian/rules to make them lowercase.
* Update patch headers.
* Provide proper ‘build-arch’ and ‘build-indep’ targets in debian/rules.
* Document input format in the manual page (closes: #572061). Thanks to
  Janusz S. Bień for the bug report.
* Use ‘slv’ (rather than ‘slo’) as language code for Slovenian.
  [slovenian-slv.diff]
* Fix package description: Slovenian is supported, Slovak is not.
* Improve documentation of the language (-l) option (closes: #602512).
  Thanks to Jari Aalto for the bug report.
* Install reasons file for vrms.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
Copyright (c) 1993-2008, Cognitive Technologies
3
 
All rights reserved.
4
 
 
5
 
����������� ��������� ��������������� � ������������� ��� � ���� ��������� ����,
6
 
��� � � �������� �����, � ����������� ��� ���, ��� ���������� ��������� �������:
7
 
 
8
 
      * ��� ��������� ��������������� ��������� ���� ������ ���������� ���������
9
 
        ���� ����������� �� ��������� �����, ���� ������ ������� � �����������
10
 
        ����� �� ��������.
11
 
      * ��� ��������� ��������������� ��������� ���� � ������������ �/��� �
12
 
        ������ ����������, ������������ ��� ���������������, ������ �����������
13
 
        ��������� ���� ���������� �� ��������� �����, ���� ������ ������� �
14
 
        ����������� ����� �� ��������.
15
 
      * �� �������� Cognitive Technologies, �� ����� �� ����������� �� �����
16
 
        ���� ������������ � �������� �������� ��������� �/��� �����������
17
 
        ���������, ���������� �� ���� ��, ��� ���������������� �����������
18
 
        ����������.
19
 
 
20
 
��� ��������� ������������� ����������� ��������� ���� �/��� ������� ������ "���
21
 
��� ����" ��� ������-���� ���� ��������, ���������� ���� ��� ���������������,
22
 
������� �������� ������������ �������� � ����������� ��� ���������� ����, �� ��
23
 
������������� ���. �� �������� ��������� ���� � �� ���� ������ ����, �������
24
 
����� �������� �/��� �������� �������������� ���������, �� � ���� ������ ��
25
 
��Ѩ� ���������������, ������� ����� �����, ���������, ����������� ���
26
 
������������� ������, ��������� � �������������� ��� ���������� ����������
27
 
������������� ������������� ��������� (������� ������ ������, ��� ������,
28
 
������� ���������, ��� ������ �/��� ������ �������, ���������� ��-�� ��������
29
 
������� ��� �/��� ������ ��������� �������� ��������� � ������� �����������,
30
 
�� �� ������������� ����� ��������), �� �� ������������� ���, ���� ���� �����
31
 
�������� ��� ������ ���� ���� �������� � ����������� ����� ������� � ������.
32
 
 
33
 
Redistribution and use in source and binary forms, with or without modification,
34
 
are permitted provided that the following conditions are met:
35
 
 
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.
44
 
 
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.
55
 
*/
56
 
 
57
 
#define _NOT_ALL_      // �� ������ ������ �����
58
 
// #define _NEED_SCALE_   // �������������� ��� ����������� ������
59
 
#define STANDARD_HEIGHT 38  // ����������� ������
60
 
 
 
2
 Copyright (c) 1993-2008, Cognitive Technologies
 
3
 All rights reserved.
 
4
 
 
5
 Разрешается повторное распространение и использование как в виде исходного кода,
 
6
 так и в двоичной форме, с изменениями или без, при соблюдении следующих условий:
 
7
 
 
8
 * При повторном распространении исходного кода должны оставаться указанное
 
9
 выше уведомление об авторском праве, этот список условий и последующий
 
10
 отказ от гарантий.
 
11
 * При повторном распространении двоичного кода в документации и/или в
 
12
 других материалах, поставляемых при распространении, должны сохраняться
 
13
 указанная выше информация об авторском праве, этот список условий и
 
14
 последующий отказ от гарантий.
 
15
 * Ни название Cognitive Technologies, ни имена ее сотрудников не могут
 
16
 быть использованы в качестве средства поддержки и/или продвижения
 
17
 продуктов, основанных на этом ПО, без предварительного письменного
 
18
 разрешения.
 
19
 
 
20
 ЭТА ПРОГРАММА ПРЕДОСТАВЛЕНА ВЛАДЕЛЬЦАМИ АВТОРСКИХ ПРАВ И/ИЛИ ДРУГИМИ ЛИЦАМИ "КАК
 
21
 ОНА ЕСТЬ" БЕЗ КАКОГО-ЛИБО ВИДА ГАРАНТИЙ, ВЫРАЖЕННЫХ ЯВНО ИЛИ ПОДРАЗУМЕВАЕМЫХ,
 
22
 ВКЛЮЧАЯ ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ И ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ, НО НЕ
 
23
 ОГРАНИЧИВАЯСЬ ИМИ. НИ ВЛАДЕЛЕЦ АВТОРСКИХ ПРАВ И НИ ОДНО ДРУГОЕ ЛИЦО, КОТОРОЕ
 
24
 МОЖЕТ ИЗМЕНЯТЬ И/ИЛИ ПОВТОРНО РАСПРОСТРАНЯТЬ ПРОГРАММУ, НИ В КОЕМ СЛУЧАЕ НЕ
 
25
 НЕСЁТ ОТВЕТСТВЕННОСТИ, ВКЛЮЧАЯ ЛЮБЫЕ ОБЩИЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ ИЛИ
 
26
 ПОСЛЕДОВАВШИЕ УБЫТКИ, СВЯЗАННЫЕ С ИСПОЛЬЗОВАНИЕМ ИЛИ ПОНЕСЕННЫЕ ВСЛЕДСТВИЕ
 
27
 НЕВОЗМОЖНОСТИ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ (ВКЛЮЧАЯ ПОТЕРИ ДАННЫХ, ИЛИ ДАННЫЕ,
 
28
 СТАВШИЕ НЕГОДНЫМИ, ИЛИ УБЫТКИ И/ИЛИ ПОТЕРИ ДОХОДОВ, ПОНЕСЕННЫЕ ИЗ-ЗА ДЕЙСТВИЙ
 
29
 ТРЕТЬИХ ЛИЦ И/ИЛИ ОТКАЗА ПРОГРАММЫ РАБОТАТЬ СОВМЕСТНО С ДРУГИМИ ПРОГРАММАМИ,
 
30
 НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМИ СЛУЧАЯМИ), НО НЕ ОГРАНИЧИВАЯСЬ ИМИ, ДАЖЕ ЕСЛИ ТАКОЙ
 
31
 ВЛАДЕЛЕЦ ИЛИ ДРУГОЕ ЛИЦО БЫЛИ ИЗВЕЩЕНЫ О ВОЗМОЖНОСТИ ТАКИХ УБЫТКОВ И ПОТЕРЬ.
 
32
 
 
33
 Redistribution and use in source and binary forms, with or without modification,
 
34
 are permitted provided that the following conditions are met:
 
35
 
 
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.
 
44
 
 
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.
 
55
 */
 
56
 
 
57
#define _NOT_ALL_      // не делать полный поиск
 
58
// #define _NEED_SCALE_   // масштабировать под стандартную высоту
 
59
#define STANDARD_HEIGHT 38  // стандартная высота
61
60
//#define _TEST_ADD_FAT_
62
61
 
63
62
#define OLEG_ACC 0
64
63
 
65
64
//#define CHECK_EQUAL
66
65
 
67
 
// ����������� ������ �� ����������
 
66
// размазывать мелких на полпиксела
68
67
//#define _USE_HALF_
69
68
 
70
69
#define MAX_ALT              5
71
70
 
72
71
#define POROG_HALF_WIDTH    4      // 21
73
72
#define POROG_HALF_HEIGHT   13     // 23
74
 
 
75
 
#include "c_types.h"
76
 
 
77
73
#include <stdlib.h>
78
74
#include <string.h>
79
 
/*#include <io.h>*/
80
75
#include <fcntl.h>
81
 
/*#include <sys\stat.h>*/
82
76
#include <stdio.h>
83
77
 
84
78
#ifdef _GETTIME_
85
 
 #include <time.h>
 
79
#include <time.h>
86
80
#endif
87
81
 
 
82
#include "minmax.h"
88
83
#include "fon.h"
89
84
#include "sfont.h"
90
85
#include "fonrec.h"
91
86
#include "ctbdefs.h"
92
87
#include "ligas.h"    // 13.09.2000
93
 
 
94
 
extern Word8 language;
95
 
 
96
 
 
97
 
WORD cmp(PBYTE r,WORD fullwb,WORD w,WORD h,welet * wl);
98
 
SINT RazmazHalf(BYTE *bSource,BYTE *bDest,SINT xbit,SINT yrow);
 
88
extern uchar language;
 
89
 
 
90
uint16_t cmp(puchar r, uint16_t fullwb, uint16_t w, uint16_t h, welet * wl);
 
91
int16_t RazmazHalf(uchar *bSource, uchar *bDest, int16_t xbit, int16_t yrow);
99
92
///////////////////////
100
93
//
101
 
// �������� ������� �����
 
94
// штрафуем дальние точки
102
95
//
103
96
 
104
97
#ifdef OLEG_ACC
105
 
static int sign_tab[513]={
106
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0
107
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 1
108
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 2
109
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 3
110
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 4
111
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 5
112
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 6
113
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 7
114
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 8
115
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 9
116
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // a
117
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // b
118
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c
119
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // d
120
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // e
121
 
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // f
122
 
1,
123
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0
124
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1
125
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2
126
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3
127
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 4
128
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 5
129
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 6
130
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 7
131
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 8
132
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 9
133
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // a
134
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // b
135
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // c
136
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // d
137
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // e
138
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  // f
139
 
};
140
 
static  int *sign;
 
98
static int sign_tab[513] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0
 
99
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 1
 
100
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 2
 
101
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 3
 
102
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 4
 
103
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 5
 
104
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 6
 
105
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 7
 
106
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 8
 
107
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 9
 
108
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // a
 
109
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // b
 
110
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // c
 
111
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // d
 
112
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // e
 
113
                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // f
 
114
                1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0
 
115
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
 
116
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
 
117
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3
 
118
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
 
119
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
 
120
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
 
121
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
 
122
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
 
123
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
 
124
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // a
 
125
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // b
 
126
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // c
 
127
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // d
 
128
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // e
 
129
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // f
 
130
                };
 
131
static int *sign;
141
132
#include "array1.h"
142
 
static int DistToWelet(PBYTE r,int fullByte,int w,int h,welet * wl,
143
 
                                           int xo,int yo,int porog,
144
 
                                           int dist1)
145
 
{
146
 
PCHAR   curr, currn,currh;
147
 
int     rbyte;
148
 
PBYTE   rr,rn;
149
 
int             dist;
150
 
 
151
 
 
152
 
curr = wl->raster + WR_MAX_WIDTH*((WR_MAX_HEIGHT-h)/2) +
153
 
                                  (WR_MAX_WIDTH-w)/2;
154
 
curr += xo + WR_MAX_WIDTH * yo; // variation
155
 
currh   = curr + WR_MAX_WIDTH * h;
156
 
rbyte=(w+7)>>3;
157
 
sign=&sign_tab[256]-dist1;
158
 
for(dist=0; curr<currh;curr += WR_MAX_WIDTH,r+=fullByte)
159
 
    {
160
 
    if( dist+8>=porog )
161
 
    {
162
 
    for(currn=curr,rr=r,rn=r+rbyte;rr!=rn; rr++, currn+=8)
163
 
        {
164
 
        dist += bit_distance[*rr](currn);
165
 
 
166
 
        if( dist > porog )
167
 
            return dist;
168
 
        }  // end rr
169
 
    }
170
 
    else
171
 
        {
172
 
        switch( rbyte )
173
 
            {
174
 
            case    1:
175
 
                dist += bit_distance[*r](curr);
176
 
                break;
177
 
            case    2:
178
 
                dist += bit_distance[*r](curr)+bit_distance[*(r+1)](curr+8);
179
 
                break;
180
 
            case    3:
181
 
                dist += bit_distance[*r](curr)+bit_distance[*(r+1)](curr+8)+
182
 
                        bit_distance[*(r+2)](curr+16);
183
 
                break;
184
 
            case    4:
185
 
                dist += bit_distance[*r](curr)+bit_distance[*(r+1)](curr+8)+
186
 
                        bit_distance[*(r+2)](curr+16)+bit_distance[*(r+3)](curr+24);
187
 
                break;
188
 
            default:
189
 
                for(currn=curr,rr=r,rn=r+rbyte;rr!=rn; rr++, currn+=8)
190
 
                    {
191
 
                    dist += bit_distance[*rr](currn);
192
 
                    }  // end rr
193
 
                break;
194
 
            }
195
 
        }
196
 
    }   // end currh
197
 
 
198
 
return (dist);
 
133
static int DistToWelet(puchar r, int fullByte, int w, int h, welet * wl,
 
134
                int xo, int yo, int porog, int dist1) {
 
135
        pchar curr, currn, currh;
 
136
        int rbyte;
 
137
        puchar rr, rn;
 
138
        int dist;
 
139
 
 
140
        curr = wl->raster + WR_MAX_WIDTH * ((WR_MAX_HEIGHT - h) / 2)
 
141
                        + (WR_MAX_WIDTH - w) / 2;
 
142
        curr += xo + WR_MAX_WIDTH * yo; // variation
 
143
        currh = curr + WR_MAX_WIDTH * h;
 
144
        rbyte = (w + 7) >> 3;
 
145
        sign = &sign_tab[256] - dist1;
 
146
        for (dist = 0; curr < currh; curr += WR_MAX_WIDTH, r += fullByte) {
 
147
                if (dist + 8 >= porog) {
 
148
                        for (currn = curr, rr = r, rn = r + rbyte; rr != rn; rr++, currn
 
149
                                        += 8) {
 
150
                                dist += bit_distance[*rr](currn);
 
151
 
 
152
                                if (dist > porog)
 
153
                                        return dist;
 
154
                        } // end rr
 
155
                } else {
 
156
                        switch (rbyte) {
 
157
                        case 1:
 
158
                                dist += bit_distance[*r](curr);
 
159
                                break;
 
160
                        case 2:
 
161
                                dist += bit_distance[*r](curr) + bit_distance[*(r + 1)](curr
 
162
                                                + 8);
 
163
                                break;
 
164
                        case 3:
 
165
                                dist += bit_distance[*r](curr) + bit_distance[*(r + 1)](curr
 
166
                                                + 8) + bit_distance[*(r + 2)](curr + 16);
 
167
                                break;
 
168
                        case 4:
 
169
                                dist += bit_distance[*r](curr) + bit_distance[*(r + 1)](curr
 
170
                                                + 8) + bit_distance[*(r + 2)](curr + 16)
 
171
                                                + bit_distance[*(r + 3)](curr + 24);
 
172
                                break;
 
173
                        default:
 
174
                                for (currn = curr, rr = r, rn = r + rbyte; rr != rn; rr++, currn
 
175
                                                += 8) {
 
176
                                        dist += bit_distance[*rr](currn);
 
177
                                } // end rr
 
178
                                break;
 
179
                        }
 
180
                }
 
181
        } // end currh
 
182
 
 
183
        return (dist);
199
184
}
200
185
///////////////////////
201
186
//
202
 
// �������� ����� cluster's
 
187
// штрафуем точки cluster's
203
188
//
204
 
static int sig_tab[513]={
205
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0
206
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1
207
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2
208
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3
209
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 4
210
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 5
211
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 6
212
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 7
213
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 8
214
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 9
215
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // a
216
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // b
217
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // c
218
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // d
219
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // e
220
 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f
221
 
0,
222
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0
223
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 1
224
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 1
225
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 3
226
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 4
227
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 5
228
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 6
229
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 7
230
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 8
231
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 9
232
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // a
233
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // b
234
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // c
235
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // d
236
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // e
237
 
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1  // f
238
 
};
 
189
static int sig_tab[513] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0
 
190
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
 
191
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
 
192
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3
 
193
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
 
194
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
 
195
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
 
196
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
 
197
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
 
198
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
 
199
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // a
 
200
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // b
 
201
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // c
 
202
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // d
 
203
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // e
 
204
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // f
 
205
                0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
 
206
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
 
207
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
 
208
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3
 
209
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
 
210
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
 
211
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
 
212
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
 
213
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
 
214
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
 
215
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // a
 
216
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // b
 
217
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // c
 
218
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // d
 
219
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // e
 
220
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // f
 
221
                };
239
222
///////////////
240
 
SINT DistWeletRazmaz(PBYTE r,int fullByte,int  w,int  h,welet * wl,
241
 
                                         int  xo,int  yo, int porog, int wei)
242
 
{
243
 
int  ww=wl->w, hh=wl->h;
244
 
PCHAR curr;
245
 
int i,j;
246
 
BYTE  cbyte;
247
 
int dist;
248
 
int startx=(WR_MAX_WIDTH-w)/2;
249
 
int starty=(WR_MAX_HEIGHT-h)/2;
250
 
int stx=(WR_MAX_WIDTH-ww)/2;   // start cluster
251
 
int sty=(WR_MAX_HEIGHT-hh)/2;
252
 
int lasty,lastx,lastx8;
253
 
BYTE maskaStart,maskaHvost;
254
 
BYTE *rr;
255
 
 
256
 
 // test
257
 
 // wei=(wl->weight)/3;  // better on sb0_037
258
 
  //bit_dist_level=wei;
259
 
  sign=&sig_tab[256]-wei;
260
 
 
261
 
  startx += xo;
262
 
  starty += yo; // variation
263
 
 
264
 
  curr = wl->raster+sty*WR_MAX_WIDTH;
265
 
  dist=0;
266
 
 
267
 
    // add upper lines
268
 
  for(i=sty;i<starty;i++,curr+=WR_MAX_WIDTH)
269
 
     for(j=stx;j<stx+ww;j++)   if(curr[j]> wei) dist++;
270
 
  if(dist > porog) return dist;
271
 
 
272
 
  lasty=MIN(starty+h,sty+hh);
273
 
  lastx=MIN(startx+w,stx+ww);
274
 
 
275
 
  if( starty < sty) r+=(sty-starty)*fullByte;
276
 
 
277
 
  if(startx < stx)
278
 
  {
279
 
   j=(stx-startx)>>3;
280
 
   r+=j;
281
 
   startx+=j;
282
 
   maskaStart = 0xFF<<(8-stx+startx);
283
 
  }
284
 
  else maskaStart = 0;   // from first bit
285
 
 
286
 
  lastx8=startx+((lastx-startx)&0xfff8);
287
 
  lastx=stx+ww;
288
 
 
289
 
  if( lastx < lastx8+8)
290
 
    maskaHvost=0xFF<<(lastx8+8-lastx);
291
 
  else
292
 
    maskaHvost=0xFF;
293
 
 
294
 
   // now - start inside frame
295
 
  for(; i < lasty;i++,curr +=WR_MAX_WIDTH,r+=fullByte)
296
 
  {
297
 
        for(j=stx;j<startx;j++)
298
 
            {
299
 
            if(curr[j] > wei )
300
 
                dist++;
301
 
            }
302
 
        if(dist > porog )
303
 
            return dist;
304
 
 
305
 
        rr=r;
306
 
                cbyte=~( (*rr) | maskaStart );
307
 
 
308
 
        for(j=startx;j<lastx8;j+=8)
309
 
        {
310
 
            dist += bit_distance[cbyte](curr+j);
311
 
            cbyte=~(*(++rr));
312
 
        }  // end j
313
 
                if(dist > porog)
314
 
                return dist;
315
 
 
316
 
                //  ������� ������ (>lastx) �� ������������ - maska!
317
 
 
318
 
                if(lastx8 < lastx)
319
 
                {
320
 
         cbyte &= maskaHvost;
321
 
                 dist += bit_distance[cbyte](curr+j);
322
 
                        if(dist > porog)
323
 
                return dist;
324
 
         j+=8;
325
 
                }
326
 
 
327
 
        // last points in row
328
 
        for(;j<lastx;j++)
329
 
            {
330
 
            if(curr[j] > wei )
331
 
                dist++;
332
 
            }
333
 
        if(dist > porog)
334
 
            return dist;
335
 
  }   // end i
336
 
 
337
 
// add down lines
338
 
  for(;i<sty+hh;i++,curr+=WR_MAX_WIDTH)
339
 
     for(j=stx;j<stx+ww;j++)   if(curr[j]> wei) dist++;
340
 
 
341
 
  return (dist);
 
223
int16_t DistWeletRazmaz(puchar r, int fullByte, int w, int h, welet * wl, int xo,
 
224
                int yo, int porog, int wei) {
 
225
        int ww = wl->w, hh = wl->h;
 
226
        pchar curr;
 
227
        int i, j;
 
228
        uchar cbyte;
 
229
        int dist;
 
230
        int startx = (WR_MAX_WIDTH - w) / 2;
 
231
        int starty = (WR_MAX_HEIGHT - h) / 2;
 
232
        int stx = (WR_MAX_WIDTH - ww) / 2; // start cluster
 
233
        int sty = (WR_MAX_HEIGHT - hh) / 2;
 
234
        int lasty, lastx, lastx8;
 
235
        uchar maskaStart, maskaHvost;
 
236
        uchar *rr;
 
237
 
 
238
        // test
 
239
        // wei=(wl->weight)/3;  // better on sb0_037
 
240
        //bit_dist_level=wei;
 
241
        sign = &sig_tab[256] - wei;
 
242
 
 
243
        startx += xo;
 
244
        starty += yo; // variation
 
245
 
 
246
        curr = wl->raster + sty * WR_MAX_WIDTH;
 
247
        dist = 0;
 
248
 
 
249
        // add upper lines
 
250
        for (i = sty; i < starty; i++, curr += WR_MAX_WIDTH)
 
251
                for (j = stx; j < stx + ww; j++)
 
252
                        if (curr[j] > wei)
 
253
                                dist++;
 
254
        if (dist > porog)
 
255
                return dist;
 
256
 
 
257
        lasty = MIN(starty + h, sty + hh);
 
258
        lastx = MIN(startx + w, stx + ww);
 
259
 
 
260
        if (starty < sty)
 
261
                r += (sty - starty) * fullByte;
 
262
 
 
263
        if (startx < stx) {
 
264
                j = (stx - startx) >> 3;
 
265
                r += j;
 
266
                startx += j;
 
267
                maskaStart = 0xFF << (8 - stx + startx);
 
268
        } else
 
269
                maskaStart = 0; // from first bit
 
270
 
 
271
        lastx8 = startx + ((lastx - startx) & 0xfff8);
 
272
        lastx = stx + ww;
 
273
 
 
274
        if (lastx < lastx8 + 8)
 
275
                maskaHvost = 0xFF << (lastx8 + 8 - lastx);
 
276
        else
 
277
                maskaHvost = 0xFF;
 
278
 
 
279
        // now - start inside frame
 
280
        for (; i < lasty; i++, curr += WR_MAX_WIDTH, r += fullByte) {
 
281
                for (j = stx; j < startx; j++) {
 
282
                        if (curr[j] > wei)
 
283
                                dist++;
 
284
                }
 
285
                if (dist > porog)
 
286
                        return dist;
 
287
 
 
288
                rr = r;
 
289
                cbyte = ~((*rr) | maskaStart);
 
290
 
 
291
                for (j = startx; j < lastx8; j += 8) {
 
292
                        dist += bit_distance[cbyte](curr + j);
 
293
                        cbyte = ~(*(++rr));
 
294
                } // end j
 
295
                if (dist > porog)
 
296
                        return dist;
 
297
 
 
298
                //  реально лишнее (>lastx) не используется - maska!
 
299
 
 
300
                if (lastx8 < lastx) {
 
301
                        cbyte &= maskaHvost;
 
302
                        dist += bit_distance[cbyte](curr + j);
 
303
                        if (dist > porog)
 
304
                                return dist;
 
305
                        j += 8;
 
306
                }
 
307
 
 
308
                // last points in row
 
309
                for (; j < lastx; j++) {
 
310
                        if (curr[j] > wei)
 
311
                                dist++;
 
312
                }
 
313
                if (dist > porog)
 
314
                        return dist;
 
315
        } // end i
 
316
 
 
317
        // add down lines
 
318
        for (; i < sty + hh; i++, curr += WR_MAX_WIDTH)
 
319
                for (j = stx; j < stx + ww; j++)
 
320
                        if (curr[j] > wei)
 
321
                                dist++;
 
322
 
 
323
        return (dist);
342
324
}
343
325
////////////////////
344
326
 
345
327
#else
346
 
static int DistToWelet(PBYTE r,int fullByte,int w,int h,welet * wl,
347
 
                                           int xo,int yo,int porog,int dist1)
 
328
static int DistToWelet(puchar r,int fullByte,int w,int h,welet * wl,
 
329
                int xo,int yo,int porog,int dist1)
348
330
{
349
 
PCHAR curr;
350
 
int   i,j,jj;
351
 
BYTE  cbyte,cc;
352
 
int rbyte;
353
 
int dist;
354
 
 
355
 
 
356
 
 curr = wl->raster + WR_MAX_WIDTH*((WR_MAX_HEIGHT-h)/2) +
357
 
                                  (WR_MAX_WIDTH-w)/2;
358
 
 curr += xo + WR_MAX_WIDTH * yo; // variation
359
 
 
360
 
 rbyte=(w+7)>>3;
361
 
 
362
 
 for(i=0,dist=0; i < h;i++,curr += WR_MAX_WIDTH,r+=fullByte)
363
 
 {
364
 
  for(j=jj=0;j<rbyte;j++)
365
 
  {
366
 
   cbyte=r[j];
367
 
   if(cbyte == 0) {jj+=8;continue;}
368
 
 
369
 
   for(cc=128;cc;cc>>=1,jj++)
370
 
   {
371
 
    if( cbyte & cc )
 
331
        pchar curr;
 
332
        int i,j,jj;
 
333
        uchar cbyte,cc;
 
334
        int rbyte;
 
335
        int dist;
 
336
 
 
337
        curr = wl->raster + WR_MAX_WIDTH*((WR_MAX_HEIGHT-h)/2) +
 
338
        (WR_MAX_WIDTH-w)/2;
 
339
        curr += xo + WR_MAX_WIDTH * yo; // variation
 
340
 
 
341
        rbyte=(w+7)>>3;
 
342
 
 
343
        for(i=0,dist=0; i < h;i++,curr += WR_MAX_WIDTH,r+=fullByte)
372
344
        {
373
 
                if( curr[jj] < dist1 )
374
 
                        dist+=2;
375
 
        else if( curr[jj] == dist1 )
376
 
                        dist++;
 
345
                for(j=jj=0;j<rbyte;j++)
 
346
                {
 
347
                        cbyte=r[j];
 
348
                        if(cbyte == 0) {jj+=8;continue;}
 
349
 
 
350
                        for(cc=128;cc;cc>>=1,jj++)
 
351
                        {
 
352
                                if( cbyte & cc )
 
353
                                {
 
354
                                        if( curr[jj] < dist1 )
 
355
                                        dist+=2;
 
356
                                        else if( curr[jj] == dist1 )
 
357
                                        dist++;
 
358
                                }
 
359
                        } // end cc
 
360
 
 
361
                        if( dist > porog ) return dist;
 
362
                } // end j
 
363
        } // end i
 
364
 
 
365
        return (dist);
 
366
}
 
367
 
 
368
///////////////////////
 
369
//
 
370
// штрафуем точки cluster's
 
371
//
 
372
int16_t DistWeletRazmaz(puchar r,int fullByte,int w,int h,welet * wl,
 
373
                int xo,int yo, int porog,int wei)
 
374
{
 
375
        int16_t ww=wl->w, hh=wl->h;
 
376
        pchar curr;
 
377
        int16_t i,j;
 
378
        uchar cbyte,cc;
 
379
        int16_t rbyte;
 
380
        int dist;
 
381
        int startx=(WR_MAX_WIDTH-w)/2;
 
382
        int starty=(WR_MAX_HEIGHT-h)/2;
 
383
        int stx=(WR_MAX_WIDTH-ww)/2; // start cluster
 
384
        int sty=(WR_MAX_HEIGHT-hh)/2;
 
385
        int lasty,lastx;
 
386
        uchar initCC;
 
387
        uchar *rr;
 
388
 
 
389
        // test
 
390
        //  wei=(wl->weight)/3;  // better on sb0_037
 
391
        // wei=wl->weight>>1;     // old version
 
392
 
 
393
        startx += xo;
 
394
        starty += yo; // variation
 
395
        rbyte=(w+7)>>3;
 
396
 
 
397
        curr = wl->raster+sty*WR_MAX_WIDTH;
 
398
        dist=0;
 
399
 
 
400
        // add upper lines
 
401
        for(i=sty;i<starty;i++,curr+=WR_MAX_WIDTH)
 
402
        for(j=stx;j<stx+ww;j++) if(curr[j]> wei) dist++;
 
403
        if(dist > porog) return dist;
 
404
 
 
405
        lasty=MIN(starty+h,sty+hh);
 
406
        lastx=MIN(startx+w,stx+ww);
 
407
        if( starty < sty) r+=(sty-starty)*fullByte;
 
408
 
 
409
        if(startx < stx)
 
410
        {       initCC=128>>((stx-startx)&7);
 
411
                r+=(stx-startx)>>3;
377
412
        }
378
 
   } // end cc
379
 
 
380
 
   if( dist > porog ) return dist;
381
 
  }  // end j
382
 
 }   // end i
383
 
 
384
 
  return (dist);
385
 
}
386
 
 
387
 
///////////////////////
388
 
//
389
 
// �������� ����� cluster's
390
 
//
391
 
SINT DistWeletRazmaz(PBYTE r,int fullByte,int  w,int  h,welet * wl,
392
 
                                         int  xo,int  yo, int porog,int wei)
393
 
{
394
 
SINT ww=wl->w, hh=wl->h;
395
 
PCHAR curr;
396
 
SINT i,j;
397
 
BYTE  cbyte,cc;
398
 
SINT rbyte;
399
 
int dist;
400
 
int startx=(WR_MAX_WIDTH-w)/2;
401
 
int starty=(WR_MAX_HEIGHT-h)/2;
402
 
int stx=(WR_MAX_WIDTH-ww)/2;   // start cluster
403
 
int sty=(WR_MAX_HEIGHT-hh)/2;
404
 
int lasty,lastx;
405
 
BYTE initCC;
406
 
BYTE *rr;
407
 
 
408
 
 // test
409
 
//  wei=(wl->weight)/3;  // better on sb0_037
410
 
 // wei=wl->weight>>1;     // old version
411
 
 
412
 
 startx += xo;
413
 
 starty += yo; // variation
414
 
 rbyte=(w+7)>>3;
415
 
 
416
 
 curr = wl->raster+sty*WR_MAX_WIDTH;
417
 
 dist=0;
418
 
 
419
 
    // add upper lines
420
 
 for(i=sty;i<starty;i++,curr+=WR_MAX_WIDTH)
421
 
     for(j=stx;j<stx+ww;j++)   if(curr[j]> wei) dist++;
422
 
 if(dist > porog) return dist;
423
 
 
424
 
 lasty=MIN(starty+h,sty+hh);
425
 
 lastx=MIN(startx+w,stx+ww);
426
 
 if( starty < sty) r+=(sty-starty)*fullByte;
427
 
 
428
 
 if(startx < stx)
429
 
 {initCC=128>>((stx-startx)&7);
430
 
  r+=(stx-startx)>>3;
431
 
 }
432
 
 else initCC=128;   // from first bit
433
 
 
434
 
   // now - start inside frame
435
 
 for(; i < lasty;i++,curr +=WR_MAX_WIDTH,r+=fullByte)
436
 
 {
437
 
  for(j=stx;j<startx;j++) if(curr[j] > wei ) dist++;
438
 
  if(dist > porog ) return dist;
439
 
 
440
 
  cc=initCC;
441
 
  rr=r;
442
 
  cbyte=*rr;
443
 
  for(;j<lastx;j++,cc>>=1)
444
 
  {
445
 
   if(cc==0) {cc=128;cbyte=*(++rr);}
446
 
   if( ((cbyte & cc)==0) && curr[j]>wei  ) dist++;
447
 
  }  // end j
448
 
  if(dist > porog) return dist;
449
 
 
450
 
   // last points in row
451
 
  for(;j<stx+ww;j++) if(curr[j] > wei ) dist++;
452
 
  if(dist > porog) return dist;
453
 
 }   // end i
454
 
 
455
 
// add down lines
456
 
  for(;i<sty+hh;i++,curr+=WR_MAX_WIDTH)
457
 
     for(j=stx;j<stx+ww;j++)   if(curr[j]> wei) dist++;
458
 
 
459
 
  return (dist);
 
413
        else initCC=128; // from first bit
 
414
 
 
415
        // now - start inside frame
 
416
        for(; i < lasty;i++,curr +=WR_MAX_WIDTH,r+=fullByte)
 
417
        {
 
418
                for(j=stx;j<startx;j++) if(curr[j] > wei ) dist++;
 
419
                if(dist > porog ) return dist;
 
420
 
 
421
                cc=initCC;
 
422
                rr=r;
 
423
                cbyte=*rr;
 
424
                for(;j<lastx;j++,cc>>=1)
 
425
                {
 
426
                        if(cc==0) {cc=128;cbyte=*(++rr);}
 
427
                        if( ((cbyte & cc)==0) && curr[j]>wei ) dist++;
 
428
                } // end j
 
429
                if(dist > porog) return dist;
 
430
 
 
431
                // last points in row
 
432
                for(;j<stx+ww;j++) if(curr[j] > wei ) dist++;
 
433
                if(dist > porog) return dist;
 
434
        } // end i
 
435
 
 
436
        // add down lines
 
437
        for(;i<sty+hh;i++,curr+=WR_MAX_WIDTH)
 
438
        for(j=stx;j<stx+ww;j++) if(curr[j]> wei) dist++;
 
439
 
 
440
        return (dist);
460
441
}
461
442
///////////////
462
443
#endif
463
444
///////////
464
445
 
465
 
int distOne(BYTE *buf,BYTE *bufrazmaz,int w,int h,int bestdist,welet *wel,int x,int y,int countRazmaz)
466
 
{
467
 
int dist,j;
468
 
int dist1, wei;
469
 
int w2,h2;
 
446
int distOne(uchar *buf, uchar *bufrazmaz, int w, int h, int bestdist,
 
447
                welet *wel, int x, int y, int countRazmaz) {
 
448
        int dist, j;
 
449
        int dist1, wei;
 
450
        int w2, h2;
470
451
 
471
452
#ifdef _USE_HALF_
472
 
        //  �� �����-�� �������, �� �� ���� ����
473
 
  if( w < POROG_HALF_WIDTH || h < POROG_HALF_HEIGHT )
474
 
  {
475
 
          //return  255 - cmp( buf, (w+7)>>3, w, h, wel);
 
453
        //  на каких-то отлично, но на иных бяка
 
454
        if( w < POROG_HALF_WIDTH || h < POROG_HALF_HEIGHT )
 
455
        {
 
456
                //return  255 - cmp( buf, (w+7)>>3, w, h, wel);
476
457
 
477
458
                //dist1 = wel->weight/10;
478
459
                //dist1 = wel->weight/3;
485
466
 
486
467
                dist1 = -dist1;
487
468
 
488
 
 
489
 
                wei =   wel->weight/3;   //  /10
 
469
                wei = wel->weight/3; //  /10
490
470
                w2 = w + 1;
491
471
                h2 = h + 1;
492
472
 
493
 
//              wei =   wel->weight/3;
494
 
//              bufrazmaz = buf;
495
 
//              w2 = w;
496
 
//              h2 = h;
497
 
  }
 
473
                //              wei =   wel->weight/3;
 
474
                //              bufrazmaz = buf;
 
475
                //              w2 = w;
 
476
                //              h2 = h;
 
477
        }
498
478
 
499
 
  else  // standard
 
479
        else // standard
500
480
#endif
501
481
 
502
 
  {
503
 
        dist1 = wel->summa/wel->fill;
504
 
 
505
 
        // not-weighted distance == 2
506
 
        if(dist1 < 64 ) dist1 *=2;
507
 
        else dist1=127;
508
 
 
509
 
        dist1=-dist1;
510
 
 
511
 
        wei=(wel->weight)/3;  // better on sb0_037
512
 
 
513
 
        w2 = w + 2;
514
 
        h2 = h + 2;
515
 
  }
516
 
 
517
 
 
518
 
  dist=DistToWelet(buf,(w+7)>>3,w,h,wel,x,y,bestdist-1,dist1);
519
 
  if(dist >= bestdist)
520
 
          return dist;
521
 
 
522
 
  if(countRazmaz <= 0)
523
 
     countRazmaz = 1;
524
 
 
 
482
        {
 
483
                dist1 = wel->summa / wel->fill;
 
484
 
 
485
                // not-weighted distance == 2
 
486
                if (dist1 < 64)
 
487
                        dist1 *= 2;
 
488
                else
 
489
                        dist1 = 127;
 
490
 
 
491
                dist1 = -dist1;
 
492
 
 
493
                wei = (wel->weight) / 3; // better on sb0_037
 
494
 
 
495
                w2 = w + 2;
 
496
                h2 = h + 2;
 
497
        }
 
498
 
 
499
        dist = DistToWelet(buf, (w + 7) >> 3, w, h, wel, x, y, bestdist - 1, dist1);
 
500
        if (dist >= bestdist)
 
501
                return dist;
 
502
 
 
503
        if (countRazmaz <= 0)
 
504
                countRazmaz = 1;
525
505
 
526
506
#ifdef _USE_HALF_
527
 
  if( w < POROG_HALF_WIDTH || h < POROG_HALF_HEIGHT )
 
507
        if( w < POROG_HALF_WIDTH || h < POROG_HALF_HEIGHT )
528
508
        j= DistWeletRazmaz(bufrazmaz,(w>>3)+1,w+1,h+1,wel,x,y,(bestdist-dist-1)*countRazmaz,wei);
529
 
  else
 
509
        else
530
510
#endif
531
511
 
532
 
    j= DistWeletRazmaz(bufrazmaz,(w2+7)>>3,w2,h2,wel,x,y,(bestdist-dist-1)*countRazmaz,wei);
 
512
        j = DistWeletRazmaz(bufrazmaz, (w2 + 7) >> 3, w2, h2, wel, x, y, (bestdist
 
513
                        - dist - 1) * countRazmaz, wei);
533
514
 
534
 
  return dist+((j+countRazmaz-1)/countRazmaz);
 
515
        return dist + ((j + countRazmaz - 1) / countRazmaz);
535
516
}
536
517
////////////
537
 
int distWelet(BYTE *buf,BYTE *bufraz,int w,int h,welet * wl,int porog,int countRazmaz)
538
 
{
539
 
 WORD best,east,west,north,south,center;
540
 
 int   lbest;   // local best
541
 
 int bound=140; //2*MIN(50,w+h);
542
 
 int initPorog=porog;
543
 
 
544
 
 best=east=west=north=south=center=lbest=0;
545
 
 
546
 
// center - special threshold??? check !!!
547
 
 center =best=distOne(buf,bufraz,w,h,bound,wl,0,0,countRazmaz);
548
 
// center =best=distOne(buf,bufraz,w,h,porog,wl,0,0);
549
 
 if(best == 0 ) return best;
550
 
 
551
 
 // test - if very bad, go away ... !!!
552
 
 if(best >= bound ) return porog+1;
553
 
 
554
 
 if(best < porog) porog=best;
555
 
 
556
 
 if((south = distOne(buf,bufraz,w,h,porog,wl, 0, 1,countRazmaz)) < best )
557
 
    best = south;
558
 
 if(best==0) return best;
559
 
 if(best < porog) porog=best;
560
 
 if((north = distOne(buf,bufraz,w,h,porog,wl, 0,-1,countRazmaz)) < best )
561
 
   best = north;
562
 
 if(best==0) return best;
563
 
 if(best < porog) porog=best;
564
 
 if((east = distOne(buf,bufraz,w,h,porog,wl, 1, 0,countRazmaz)) < best )
565
 
    best = east;
566
 
 if(best==0) return best;
567
 
 if(best < porog) porog=best;
568
 
 if((west = distOne(buf,bufraz,w,h,porog,wl,-1, 0,countRazmaz)) < best )
569
 
    best = west;
570
 
 
571
 
 if(best==0) return best;
572
 
 if(best < porog) porog=best;
573
 
 
574
 
 if(best < north && best < south && best < east && best < west)
575
 
         return best;
576
 
 
577
 
 // nothing good ?
578
 
 if( best >= initPorog)
579
 
         return best;
580
 
 
581
 
 center=best;  // to save old best for compare
582
 
 // where try move ? - now two positions may be
583
 
 if( north == center || east == center )
584
 
 {
585
 
  if((lbest = distOne(buf,bufraz,w,h,porog,wl,1,-1,countRazmaz)) < best )
586
 
  {
587
 
    best = lbest;
588
 
        if(best < porog) porog=best;
589
 
  }
590
 
 }
591
 
 if(east == center || south == center )
592
 
 {
593
 
  if((lbest = distOne(buf,bufraz,w,h,porog,wl,1, 1,countRazmaz)) < best )
594
 
  {
595
 
    best = lbest;
596
 
        if(best < porog) porog=best;
597
 
  }
598
 
 }
599
 
 if(south == center || west == center)
600
 
 {
601
 
  if((lbest = distOne(buf,bufraz,w,h,porog,wl,-1, 1,countRazmaz)) < best )
602
 
  {
603
 
    best = lbest;
604
 
        if(best < porog) porog=best;
605
 
  }
606
 
 }
607
 
 if( west == center || north == center)
608
 
 {
609
 
  if((lbest = distOne(buf,bufraz,w,h,porog,wl,-1,-1,countRazmaz)) < best )
610
 
    best = lbest;
611
 
 }
612
 
 
613
 
 return best;
 
518
int distWelet(uchar *buf, uchar *bufraz, int w, int h, welet * wl, int porog,
 
519
                int countRazmaz) {
 
520
        uint16_t best, east, west, north, south, center;
 
521
        int lbest; // local best
 
522
        int bound = 140; //2*MIN(50,w+h);
 
523
        int initPorog = porog;
 
524
 
 
525
        best = east = west = north = south = center = lbest = 0;
 
526
 
 
527
        // center - special threshold??? check !!!
 
528
        center = best = distOne(buf, bufraz, w, h, bound, wl, 0, 0, countRazmaz);
 
529
        // center =best=distOne(buf,bufraz,w,h,porog,wl,0,0);
 
530
        if (best == 0)
 
531
                return best;
 
532
 
 
533
        // test - if very bad, go away ... !!!
 
534
        if (best >= bound)
 
535
                return porog + 1;
 
536
 
 
537
        if (best < porog)
 
538
                porog = best;
 
539
 
 
540
        if ((south = distOne(buf, bufraz, w, h, porog, wl, 0, 1, countRazmaz))
 
541
                        < best)
 
542
                best = south;
 
543
        if (best == 0)
 
544
                return best;
 
545
        if (best < porog)
 
546
                porog = best;
 
547
        if ((north = distOne(buf, bufraz, w, h, porog, wl, 0, -1, countRazmaz))
 
548
                        < best)
 
549
                best = north;
 
550
        if (best == 0)
 
551
                return best;
 
552
        if (best < porog)
 
553
                porog = best;
 
554
        if ((east = distOne(buf, bufraz, w, h, porog, wl, 1, 0, countRazmaz))
 
555
                        < best)
 
556
                best = east;
 
557
        if (best == 0)
 
558
                return best;
 
559
        if (best < porog)
 
560
                porog = best;
 
561
        if ((west = distOne(buf, bufraz, w, h, porog, wl, -1, 0, countRazmaz))
 
562
                        < best)
 
563
                best = west;
 
564
 
 
565
        if (best == 0)
 
566
                return best;
 
567
        if (best < porog)
 
568
                porog = best;
 
569
 
 
570
        if (best < north && best < south && best < east && best < west)
 
571
                return best;
 
572
 
 
573
        // nothing good ?
 
574
        if (best >= initPorog)
 
575
                return best;
 
576
 
 
577
        center = best; // to save old best for compare
 
578
        // where try move ? - now two positions may be
 
579
        if (north == center || east == center) {
 
580
                if ((lbest = distOne(buf, bufraz, w, h, porog, wl, 1, -1, countRazmaz))
 
581
                                < best) {
 
582
                        best = lbest;
 
583
                        if (best < porog)
 
584
                                porog = best;
 
585
                }
 
586
        }
 
587
        if (east == center || south == center) {
 
588
                if ((lbest = distOne(buf, bufraz, w, h, porog, wl, 1, 1, countRazmaz))
 
589
                                < best) {
 
590
                        best = lbest;
 
591
                        if (best < porog)
 
592
                                porog = best;
 
593
                }
 
594
        }
 
595
        if (south == center || west == center) {
 
596
                if ((lbest = distOne(buf, bufraz, w, h, porog, wl, -1, 1, countRazmaz))
 
597
                                < best) {
 
598
                        best = lbest;
 
599
                        if (best < porog)
 
600
                                porog = best;
 
601
                }
 
602
        }
 
603
        if (west == center || north == center) {
 
604
                if ((lbest = distOne(buf, bufraz, w, h, porog, wl, -1, -1, countRazmaz))
 
605
                                < best)
 
606
                        best = lbest;
 
607
        }
 
608
 
 
609
        return best;
614
610
}
615
611
 
616
612
///////////////////////////
617
 
// 0xba - ����������� ��� i � ���������� ������
618
 
static const char Palki[]="!1Iil";  //  \xba";
 
613
// 0xba - обозначение для i с приклееной точкой
 
614
static const char Palki[] = "!1Iil"; //  \xba";
619
615
 
620
616
/////////////////
621
 
static int LookBestClusters(int w,int h,BYTE *buf,BYTE *bufrazmaz,
622
 
                      int NumClus, int porog,welet *wel,
623
 
            RECRESULT *recres,int maxNames,int nInCTB,
624
 
                        int col,int row,int countRazmaz)
625
 
{
626
 
 int i,j;
627
 
 int dist;
628
 
 int num=0;
629
 
 
630
 
 for(i=num=0 ;i<NumClus;i++,wel++)
631
 
 {
632
 
  if( wel->invalid ) continue;
633
 
  if( !(wel->attr & FON_CLU_SOLID)  ) continue;
634
 
 
635
 
  // �� ������������ ���� ?
636
 
  if( wel->weight == 1 &&
637
 
          (wel->nInCTB ==nInCTB ||
638
 
           //wel->sr_col == col && wel->sr_row==row
639
 
           abs(col-wel->sr_col)<=1 && abs(row-wel->sr_row)<=1
640
 
          )
641
 
        )
642
 
//        wel-> work < 230 )
643
 
          continue;
644
 
//   dist=(255 - wel->work + 4)/(2*STRAFPOINT) ;
645
 
 
646
 
  if( wel->num < 0 )  // �� �� ������ ��������
647
 
           continue;
648
 
 
649
 
  // check for height likeness
650
 
  j=abs(wel->mh-h);
651
 
 
652
 
  if( strchr(Palki,wel->let) ||
653
 
          wel->let == liga_i ||
654
 
          (language == LANG_TURKISH &&  // 30.05.2002 E.P.
655
 
                (wel->let==i_sans_accent||wel->let==II_dot_accent)
656
 
          )
657
 
        )
658
 
  {
659
 
         if(  j*5 >  MIN(h,wel->mh)  )
660
 
           continue;
661
 
  }
662
 
  else
663
 
  {
664
 
   if( j > 2 && j*4 >  MAX(h,wel->mh)  )
665
 
           continue;
666
 
  }
667
 
 
668
 
  j=abs(wel->mw-w);
669
 
  if( j > 3 && j*3 >= MAX(w,wel->mw) ) continue;
670
 
 
671
 
  dist=distWelet(buf,bufrazmaz,w,h,wel,porog+1,countRazmaz);
672
 
 
673
 
  if(dist <= porog)
674
 
  { num=AddVersion( recres,(BYTE)wel->let,(BYTE)(255-dist),i,
675
 
                    num,maxNames);
676
 
    if(num>=maxNames)
677
 
         {porog=255-recres[maxNames-1].prob-1;
678
 
          if(porog < 0) break;
679
 
         }
680
 
//      if(dist==0) break;
681
 
  }
682
 
 
683
 
 }
684
 
 
685
 
 for(i=0;i<num;i++)
686
 
   {
687
 
         j=255-recres[i].prob;
688
 
         j=255-STRAFPOINT*j;
689
 
          // ����� ������ �� �����
690
 
     if( j<= 0 ) break;
691
 
    // for every point - add straf
692
 
     recres[i].prob=(BYTE)j;
693
 
        }
694
 
 num=i;
695
 
 
696
 
 return num;
 
617
static int LookBestClusters(int w, int h, uchar *buf, uchar *bufrazmaz,
 
618
                int NumClus, int porog, welet *wel, RECRESULT *recres, int maxNames,
 
619
                int nInCTB, int col, int row, int countRazmaz) {
 
620
        int i, j;
 
621
        int dist;
 
622
        int num = 0;
 
623
 
 
624
        for (i = num = 0; i < NumClus; i++, wel++) {
 
625
                if (wel->invalid)
 
626
                        continue;
 
627
                if (!(wel->attr & FON_CLU_SOLID))
 
628
                        continue;
 
629
 
 
630
                // не распознавать себя ?
 
631
                if (wel->weight == 1 && (wel->nInCTB == nInCTB ||
 
632
                //wel->sr_col == col && wel->sr_row==row
 
633
                                abs(col - wel->sr_col) <= 1 && abs(row - wel->sr_row) <= 1))
 
634
                        //        wel-> work < 230 )
 
635
                        continue;
 
636
                //   dist=(255 - wel->work + 4)/(2*STRAFPOINT) ;
 
637
 
 
638
                if (wel->num < 0) // не из нашего алфавита
 
639
                        continue;
 
640
 
 
641
                // check for height likeness
 
642
                j = abs(wel->mh - h);
 
643
 
 
644
                if (strchr(Palki, wel->let) || wel->let == liga_i || (language
 
645
                                == LANG_TURKISH && // 30.05.2002 E.P.
 
646
                                (wel->let == i_sans_accent || wel->let == II_dot_accent))) {
 
647
                        if (j * 5 > MIN(h, wel->mh))
 
648
                                continue;
 
649
                } else {
 
650
                        if (j > 2 && j * 4 > MAX(h, wel->mh))
 
651
                                continue;
 
652
                }
 
653
 
 
654
                j = abs(wel->mw - w);
 
655
                if (j > 3 && j * 3 >= MAX(w, wel->mw))
 
656
                        continue;
 
657
 
 
658
                dist = distWelet(buf, bufrazmaz, w, h, wel, porog + 1, countRazmaz);
 
659
 
 
660
                if (dist <= porog) {
 
661
                        num = AddVersion(recres, (uchar) wel->let, (uchar)(255 - dist), i,
 
662
                                        num, maxNames);
 
663
                        if (num >= maxNames) {
 
664
                                porog = 255 - recres[maxNames - 1].prob - 1;
 
665
                                if (porog < 0)
 
666
                                        break;
 
667
                        }
 
668
                        //      if(dist==0) break;
 
669
                }
 
670
 
 
671
        }
 
672
 
 
673
        for (i = 0; i < num; i++) {
 
674
                j = 255 - recres[i].prob;
 
675
                j = 255 - STRAFPOINT * j;
 
676
                // очень слабые не нужны
 
677
                if (j <= 0)
 
678
                        break;
 
679
                // for every point - add straf
 
680
                recres[i].prob = (uchar) j;
 
681
        }
 
682
        num = i;
 
683
 
 
684
        return num;
697
685
}
698
686
 
699
687
///////////////////////
700
688
 
701
 
int AddTestAlt(Word8 prob,int numAlt,FonTestInfo *attr,
702
 
                           welet *wel,int nClust)
703
 
{
704
 
    Word8 flg =CTB_PRINT_FONT;
705
 
        int j,k;
706
 
 
707
 
        if(wel->attr & FON_CLU_ITALIC)
708
 
           flg|=CTB_PRINT_ITALIC;
709
 
        if(wel->attr & FON_CLU_BOLD)
710
 
           flg|=CTB_PRINT_BOLD;
711
 
    if(wel->attr & FON_CLU_SERIF)
712
 
           flg|=CTB_PRINT_SERIFIC;
713
 
        if(wel->attr & FON_CLU_GELV)
714
 
           flg|=CTB_PRINT_GELV;
715
 
        if(wel->attr & FON_CLU_NARROW)
716
 
           flg|=CTB_PRINT_NARROW;
717
 
 
718
 
    for(j=0;j<numAlt;j++ )
719
 
         {
720
 
           if( attr[j].flag == flg      )
721
 
           {
722
 
        if( attr[j].prob < prob )
723
 
                {
724
 
         attr[j].prob   = prob;
725
 
                 attr[j].kegl   = wel->kegl;
726
 
                 attr[j].nClust = nClust;
 
689
int AddTestAlt(uchar prob, int numAlt, FonTestInfo *attr, welet *wel,
 
690
                int nClust) {
 
691
        uchar flg = CTB_PRINT_FONT;
 
692
        int j, k;
 
693
 
 
694
        if (wel->attr & FON_CLU_ITALIC)
 
695
                flg |= CTB_PRINT_ITALIC;
 
696
        if (wel->attr & FON_CLU_BOLD)
 
697
                flg |= CTB_PRINT_BOLD;
 
698
        if (wel->attr & FON_CLU_SERIF)
 
699
                flg |= CTB_PRINT_SERIFIC;
 
700
        if (wel->attr & FON_CLU_GELV)
 
701
                flg |= CTB_PRINT_GELV;
 
702
        if (wel->attr & FON_CLU_NARROW)
 
703
                flg |= CTB_PRINT_NARROW;
 
704
 
 
705
        for (j = 0; j < numAlt; j++) {
 
706
                if (attr[j].flag == flg) {
 
707
                        if (attr[j].prob < prob) {
 
708
                                attr[j].prob = prob;
 
709
                                attr[j].kegl = wel->kegl;
 
710
                                attr[j].nClust = nClust;
 
711
                        }
 
712
                        return numAlt;
727
713
                }
 
714
                if (prob > attr[j].prob)
 
715
                        break;
 
716
        }
 
717
 
 
718
        if (j >= MAXCHECKALT)
728
719
                return numAlt;
729
 
           }
730
 
           if(prob > attr[j].prob) break;
731
 
         }
732
 
 
733
 
   if( j >= MAXCHECKALT )
734
 
           return numAlt;
735
 
 
736
 
          // was such attr ?
737
 
   for(k=j+1;k<numAlt;k++ )
738
 
   {
739
 
      if( attr[k].flag == flg )
740
 
                  break;
741
 
   }
742
 
   if(k==MAXCHECKALT )
743
 
           k--;
744
 
   else if(k > numAlt)
745
 
           numAlt++;
746
 
 
747
 
   if( j < k )
748
 
    memmove(attr+j+1,attr+j,sizeof(FonTestInfo)*(k-j));
749
 
 
750
 
   attr[j].prob   = prob;
751
 
   attr[j].flag   = flg;
752
 
   attr[j].kegl   = wel->kegl;
753
 
   attr[j].nClust = nClust;
754
 
 
755
 
   return numAlt;
 
720
 
 
721
        // was such attr ?
 
722
        for (k = j + 1; k < numAlt; k++) {
 
723
                if (attr[k].flag == flg)
 
724
                        break;
 
725
        }
 
726
        if (k == MAXCHECKALT)
 
727
                k--;
 
728
        else if (k > numAlt)
 
729
                numAlt++;
 
730
 
 
731
        if (j < k)
 
732
                memmove(attr + j + 1, attr + j, sizeof(FonTestInfo) * (k - j));
 
733
 
 
734
        attr[j].prob = prob;
 
735
        attr[j].flag = flg;
 
736
        attr[j].kegl = wel->kegl;
 
737
        attr[j].nClust = nClust;
 
738
 
 
739
        return numAlt;
756
740
}
757
741
/////////////
758
 
static SINT CheckLetter(SINT w,SINT h,BYTE *buf,BYTE *bufrazmaz,
759
 
                       FONBASE *fbase,int porog, int let,FonTestInfo *attr ,Int16 nInCTB)
760
 
{
761
 
 SINT dist;
762
 
 int num=0,i;
763
 
 int numAlt=0;
764
 
 welet *wel;
765
 
 
766
 
 if( let<0 || let > 255)
767
 
         return -1;
768
 
 
769
 
 i=fbase->first[let];
770
 
 for(num=0;i>0; i=wel->next)
771
 
 {
772
 
  wel=fbase->start+i-1;
773
 
 
774
 
  if( wel->let != let ) continue;
775
 
  if( wel->invalid ) continue;
776
 
  if( !(wel->attr & FON_CLU_SOLID)  ) continue;
777
 
  if( wel->weight == 1 &&  wel->nInCTB == nInCTB )
778
 
          continue;
779
 
 
780
 
  num++;
781
 
  dist=distWelet(buf,bufrazmaz,w,h,wel,porog+1,1);
782
 
 
783
 
  if(dist <= porog)
784
 
  {
785
 
   Word8 prob=MAX(0,255-STRAFPOINT*dist);
786
 
   numAlt = AddTestAlt( prob,numAlt,attr,wel,i);
787
 
  }
788
 
 
789
 
 }
790
 
 
791
 
 if(num <= 0) return -1;   // no such letter
792
 
 return numAlt;
 
742
static int16_t CheckLetter(int16_t w, int16_t h, uchar *buf, uchar *bufrazmaz,
 
743
                FONBASE *fbase, int porog, int let, FonTestInfo *attr, int16_t nInCTB) {
 
744
        int16_t dist;
 
745
        int num = 0, i;
 
746
        int numAlt = 0;
 
747
        welet *wel;
 
748
 
 
749
        if (let < 0 || let > 255)
 
750
                return -1;
 
751
 
 
752
        i = fbase->first[let];
 
753
        for (num = 0; i > 0; i = wel->next) {
 
754
                wel = fbase->start + i - 1;
 
755
 
 
756
                if (wel->let != let)
 
757
                        continue;
 
758
                if (wel->invalid)
 
759
                        continue;
 
760
                if (!(wel->attr & FON_CLU_SOLID))
 
761
                        continue;
 
762
                if (wel->weight == 1 && wel->nInCTB == nInCTB)
 
763
                        continue;
 
764
 
 
765
                num++;
 
766
                dist = distWelet(buf, bufrazmaz, w, h, wel, porog + 1, 1);
 
767
 
 
768
                if (dist <= porog) {
 
769
                        uchar prob = MAX(0, 255 - STRAFPOINT * dist);
 
770
                        numAlt = AddTestAlt(prob, numAlt, attr, wel, i);
 
771
                }
 
772
 
 
773
        }
 
774
 
 
775
        if (num <= 0)
 
776
                return -1; // no such letter
 
777
        return numAlt;
793
778
}
794
779
 
795
780
///////////////////////
796
 
static BYTE buf[REC_MAX_RASTER_SIZE];
797
 
static BYTE bufrazmaz[REC_MAX_RASTER_SIZE];
798
 
static BYTE const mask0[8]={255,128,192,224,240,248,252,254};
 
781
static uchar buf[REC_MAX_RASTER_SIZE];
 
782
static uchar bufrazmaz[REC_MAX_RASTER_SIZE];
 
783
static uchar const mask0[8] = { 255, 128, 192, 224, 240, 248, 252, 254 };
799
784
//////////////
800
 
SINT RecogClu(BYTE *rast,SINT xbyte,SINT xbit,SINT yrow,
801
 
              RECRESULT *recres, SINT maxNames,
802
 
              welet *wl,int numWel,
803
 
              int porog ,int nInCTB, Int16 col, Int16 row,
804
 
                          Int32 countRazmaz)
805
 
{
806
 
 int i;
807
 
 int rbyte=(xbit+7)>>3;
808
 
 BYTE *b1;
809
 
 BYTE hvost=mask0[xbit&7];
810
 
 
811
 
 
812
 
 if(wl==NULL || numWel <= 0) return 0;
813
 
 if(xbyte*yrow > REC_MAX_RASTER_SIZE) yrow=REC_MAX_RASTER_SIZE/xbyte;
814
 
 
815
 
 for(i=0,b1=buf;i<yrow;i++,b1+=rbyte,rast+=xbyte)
816
 
 {
817
 
         memcpy(b1,rast,rbyte);
818
 
         b1[rbyte-1]&=hvost;
819
 
 }
 
785
int16_t RecogClu(uchar *rast, int16_t xbyte, int16_t xbit, int16_t yrow, RECRESULT *recres,
 
786
                int16_t maxNames, welet *wl, int numWel, int porog, int nInCTB,
 
787
                int16_t col, int16_t row, int32_t countRazmaz) {
 
788
        int i;
 
789
        int rbyte = (xbit + 7) >> 3;
 
790
        uchar *b1;
 
791
        uchar hvost = mask0[xbit & 7];
 
792
 
 
793
        if (wl == NULL || numWel <= 0)
 
794
                return 0;
 
795
        if (xbyte * yrow > REC_MAX_RASTER_SIZE)
 
796
                yrow = REC_MAX_RASTER_SIZE / xbyte;
 
797
 
 
798
        for (i = 0, b1 = buf; i < yrow; i++, b1 += rbyte, rast += xbyte) {
 
799
                memcpy(b1, rast, rbyte);
 
800
                b1[rbyte - 1] &= hvost;
 
801
        }
820
802
 
821
803
#ifdef _USE_HALF_
822
 
 if( xbit < POROG_HALF_WIDTH || yrow < POROG_HALF_HEIGHT )
823
 
  RazmazHalf(buf,bufrazmaz,xbit,yrow);
824
 
 else
 
804
        if( xbit < POROG_HALF_WIDTH || yrow < POROG_HALF_HEIGHT )
 
805
        RazmazHalf(buf,bufrazmaz,xbit,yrow);
 
806
        else
825
807
#endif
826
 
  Razmaz2(buf,bufrazmaz,xbit,yrow, 0,POROG_ANGLES);
827
 
 
828
 
  if(porog < 0)
829
 
          porog=MIN(50,xbit+yrow+4);
830
 
 
831
 
  if(maxNames > MAX_ALT )
832
 
      maxNames=MAX_ALT;
833
 
 
834
 
  i=LookBestClusters(xbit,yrow,buf,bufrazmaz,
835
 
                      numWel,porog,wl,recres, maxNames,nInCTB,col,row,countRazmaz);
 
808
        Razmaz2(buf, bufrazmaz, xbit, yrow, 0, POROG_ANGLES);
 
809
 
 
810
        if (porog < 0)
 
811
                porog = MIN(50, xbit + yrow + 4);
 
812
 
 
813
        if (maxNames > MAX_ALT)
 
814
                maxNames = MAX_ALT;
 
815
 
 
816
        i = LookBestClusters(xbit, yrow, buf, bufrazmaz, numWel, porog, wl, recres,
 
817
                        maxNames, nInCTB, col, row, countRazmaz);
836
818
 
837
819
#ifdef CHECK_EQUAL
838
 
  if( i > 1 &&
839
 
          recres[0].prob - 3 <= recres[1].prob )
840
 
  {
841
 
   int CheckRaster(PBYTE r,WORD fullBytes,WORD w,WORD h,
 
820
        if( i > 1 &&
 
821
                        recres[0].prob - 3 <= recres[1].prob )
 
822
        {
 
823
                int CheckRaster(puchar r,uint16_t fullBytes,uint16_t w,uint16_t h,
842
824
                                welet *wel,int inBase,int let);
843
 
   int prob0,prob1;
844
 
   prob0= CheckRaster(buf,rbyte,xbit,yrow,wl,numWel,recres[0].name);
845
 
   prob1= CheckRaster(buf,rbyte,xbit,yrow,wl,numWel,recres[1].name);
846
 
   if( prob1 > prob0 )
847
 
   {
848
 
      RECRESULT tmpRec=recres[0];
849
 
          recres[0]=recres[1];
850
 
      recres[1]=tmpRec;
851
 
 
852
 
   }
853
 
 
854
 
   if(prob1 != prob0 )
855
 
   { int j=1;
856
 
     for(;j<i;j++)
857
 
                  recres[j].prob--;
858
 
   }
859
 
  }
860
 
#endif
861
 
 
862
 
#ifdef _TEST_ADD_FAT_
863
 
  {
864
 
          static int AddTestRecogCollection( BYTE *rast,int xbit,int yrow,
865
 
                int num,RECRESULT *recres,  welet *wl,int numWel );
866
 
          i=AddTestRecogCollection ( buf,(int)xbit,(int)yrow,
867
 
                  i, recres, wl,(int)numWel);
868
 
  }
869
 
#endif
870
 
 
871
 
  return i;
872
 
}
873
 
///////////////////////////
874
 
SINT CheckClu(BYTE *rast,SINT xbyte,SINT xbit,SINT yrow,
875
 
                          FONBASE *fbase,int let,FonTestInfo *attr,Int16 nInCTB)
876
 
{
877
 
 int i;
878
 
 int rbyte=(xbit+7)>>3;
879
 
 BYTE *b1;
880
 
 int porog;
881
 
 BYTE hvost=mask0[xbit&7];
882
 
 
883
 
 if( fbase==NULL || fbase->inBase <= 0)
884
 
         return -1;
885
 
 if(xbyte*yrow > REC_MAX_RASTER_SIZE) yrow=REC_MAX_RASTER_SIZE/xbyte;
886
 
 
887
 
 for(i=0,b1=buf;i<yrow;i++,b1+=rbyte,rast+=xbyte)
888
 
 {
889
 
         memcpy(b1,rast,rbyte);
890
 
         b1[rbyte-1]&=hvost;
891
 
 }
892
 
 
893
 
 
894
 
#ifdef _USE_HALF_
895
 
 if( xbit < POROG_HALF_WIDTH || yrow < POROG_HALF_HEIGHT )
896
 
  RazmazHalf(buf,bufrazmaz,xbit,yrow);
897
 
 else
898
 
#endif
899
 
  Razmaz2(buf,bufrazmaz,xbit,yrow,
900
 
    0,(SINT)POROG_ANGLES );
901
 
 
902
 
  //porog=MAX(xbit,yrow);
903
 
  porog=MIN(50,xbit+yrow);
904
 
 
905
 
  i=CheckLetter(xbit,yrow,buf,bufrazmaz,
906
 
                        fbase, porog, let, attr,nInCTB);
907
 
  return i;
908
 
}
909
 
///////////////////////////
910
 
int CompareCluster(BYTE *rast,int xbyte,int xbit,int yrow,welet *wel,
911
 
                                   int movex,int movey)
912
 
{
913
 
 int i;
914
 
 int rbyte=(xbit+7)>>3;
915
 
 BYTE *b1;
916
 
 BYTE hvost=mask0[xbit&7];
917
 
 
918
 
 if( wel==NULL ) return 0;
919
 
 if(xbyte*yrow > REC_MAX_RASTER_SIZE) yrow=REC_MAX_RASTER_SIZE/xbyte;
920
 
 
921
 
 // to static buffer
922
 
 for(i=0,b1=buf;i<yrow;i++,b1+=rbyte,rast+=xbyte)
923
 
 {memcpy(b1,rast,rbyte);
924
 
  b1[rbyte-1]&=hvost;
925
 
 }
926
 
 
927
 
#ifdef _USE_HALF_
928
 
 if( xbit < POROG_HALF_WIDTH || yrow < POROG_HALF_HEIGHT )
929
 
  RazmazHalf(buf,bufrazmaz,(SINT)xbit,(SINT)yrow);
930
 
 else
931
 
#endif
932
 
  Razmaz2(buf,bufrazmaz,(SINT)xbit,(SINT)yrow,
933
 
   (SINT)0,(SINT)POROG_ANGLES);
934
 
 
935
 
  i=distOne(buf,bufrazmaz,xbit,yrow,85,wel,movex,movey,1);
936
 
  return MAX(0,255-STRAFPOINT*i);
937
 
}
938
 
///////////////////////////
939
 
#ifdef _TEST_ADD_FAT_
940
 
 
941
 
static int DistToWeletReal(PBYTE r,int fullByte,int w,int h,welet * wl,
942
 
                                           int xo,int yo,int porog)
943
 
{
944
 
PCHAR curr;
945
 
int   i,j,jj;
946
 
BYTE  cbyte,cc;
947
 
int rbyte;
948
 
int dist;
949
 
 
950
 
// dist1 = wl->summa/wl->fill;
951
 
 
952
 
 curr = wl->raster + WR_MAX_WIDTH*((WR_MAX_HEIGHT-h)/2) +
953
 
                                  (WR_MAX_WIDTH-w)/2;
954
 
 curr += xo + WR_MAX_WIDTH * yo; // variation
955
 
 
956
 
 rbyte=(w+7)>>3;
957
 
 
958
 
 for(i=0,dist=0; i < h;i++,curr += WR_MAX_WIDTH,r+=fullByte)
959
 
 {
960
 
  for(j=jj=0;j<rbyte;j++)
961
 
  {
962
 
   cbyte=r[j];
963
 
   if(cbyte == 0) {jj+=8;continue;}
964
 
 
965
 
   for(cc=128;cc;cc>>=1,jj++)
966
 
   {
967
 
    if( cbyte & cc )
968
 
        {
969
 
                if( curr[jj] < 0 )
970
 
                        dist+=2;
971
 
        }
972
 
        else
973
 
                if( curr[jj] > 0 ) dist++;
974
 
   } // end cc
975
 
 
976
 
   if( dist > porog ) return dist;
977
 
  }  // end j
978
 
 }   // end i
979
 
 
980
 
  return (dist);
 
825
                int prob0,prob1;
 
826
                prob0= CheckRaster(buf,rbyte,xbit,yrow,wl,numWel,recres[0].name);
 
827
                prob1= CheckRaster(buf,rbyte,xbit,yrow,wl,numWel,recres[1].name);
 
828
                if( prob1 > prob0 )
 
829
                {
 
830
                        RECRESULT tmpRec=recres[0];
 
831
                        recres[0]=recres[1];
 
832
                        recres[1]=tmpRec;
 
833
 
 
834
                }
 
835
 
 
836
                if(prob1 != prob0 )
 
837
                {       int j=1;
 
838
                        for(;j<i;j++)
 
839
                        recres[j].prob--;
 
840
                }
 
841
        }
 
842
#endif
 
843
 
 
844
#ifdef _TEST_ADD_FAT_
 
845
        {
 
846
                static int AddTestRecogCollection( uchar *rast,int xbit,int yrow,
 
847
                                int num,RECRESULT *recres, welet *wl,int numWel );
 
848
                i=AddTestRecogCollection ( buf,(int)xbit,(int)yrow,
 
849
                                i, recres, wl,(int)numWel);
 
850
        }
 
851
#endif
 
852
 
 
853
        return i;
 
854
}
 
855
///////////////////////////
 
856
int16_t CheckClu(uchar *rast, int16_t xbyte, int16_t xbit, int16_t yrow, FONBASE *fbase,
 
857
                int let, FonTestInfo *attr, int16_t nInCTB) {
 
858
        int i;
 
859
        int rbyte = (xbit + 7) >> 3;
 
860
        uchar *b1;
 
861
        int porog;
 
862
        uchar hvost = mask0[xbit & 7];
 
863
 
 
864
        if (fbase == NULL || fbase->inBase <= 0)
 
865
                return -1;
 
866
        if (xbyte * yrow > REC_MAX_RASTER_SIZE)
 
867
                yrow = REC_MAX_RASTER_SIZE / xbyte;
 
868
 
 
869
        for (i = 0, b1 = buf; i < yrow; i++, b1 += rbyte, rast += xbyte) {
 
870
                memcpy(b1, rast, rbyte);
 
871
                b1[rbyte - 1] &= hvost;
 
872
        }
 
873
 
 
874
#ifdef _USE_HALF_
 
875
        if( xbit < POROG_HALF_WIDTH || yrow < POROG_HALF_HEIGHT )
 
876
        RazmazHalf(buf,bufrazmaz,xbit,yrow);
 
877
        else
 
878
#endif
 
879
        Razmaz2(buf, bufrazmaz, xbit, yrow, 0, (int16_t) POROG_ANGLES);
 
880
 
 
881
        //porog=MAX(xbit,yrow);
 
882
        porog = MIN(50, xbit + yrow);
 
883
 
 
884
        i
 
885
                        = CheckLetter(xbit, yrow, buf, bufrazmaz, fbase, porog, let, attr,
 
886
                                        nInCTB);
 
887
        return i;
 
888
}
 
889
///////////////////////////
 
890
int CompareCluster(uchar *rast, int xbyte, int xbit, int yrow, welet *wel,
 
891
                int movex, int movey) {
 
892
        int i;
 
893
        int rbyte = (xbit + 7) >> 3;
 
894
        uchar *b1;
 
895
        uchar hvost = mask0[xbit & 7];
 
896
 
 
897
        if (wel == NULL)
 
898
                return 0;
 
899
        if (xbyte * yrow > REC_MAX_RASTER_SIZE)
 
900
                yrow = REC_MAX_RASTER_SIZE / xbyte;
 
901
 
 
902
        // to static buffer
 
903
        for (i = 0, b1 = buf; i < yrow; i++, b1 += rbyte, rast += xbyte) {
 
904
                memcpy(b1, rast, rbyte);
 
905
                b1[rbyte - 1] &= hvost;
 
906
        }
 
907
 
 
908
#ifdef _USE_HALF_
 
909
        if( xbit < POROG_HALF_WIDTH || yrow < POROG_HALF_HEIGHT )
 
910
        RazmazHalf(buf,bufrazmaz,(int16_t)xbit,(int16_t)yrow);
 
911
        else
 
912
#endif
 
913
        Razmaz2(buf, bufrazmaz, (int16_t) xbit, (int16_t) yrow, (int16_t) 0,
 
914
                        (int16_t) POROG_ANGLES);
 
915
 
 
916
        i = distOne(buf, bufrazmaz, xbit, yrow, 85, wel, movex, movey, 1);
 
917
        return MAX(0, 255 - STRAFPOINT * i);
 
918
}
 
919
///////////////////////////
 
920
#ifdef _TEST_ADD_FAT_
 
921
 
 
922
static int DistToWeletReal(puchar r,int fullByte,int w,int h,welet * wl,
 
923
                int xo,int yo,int porog)
 
924
{
 
925
        pchar curr;
 
926
        int i,j,jj;
 
927
        uchar cbyte,cc;
 
928
        int rbyte;
 
929
        int dist;
 
930
 
 
931
        // dist1 = wl->summa/wl->fill;
 
932
 
 
933
        curr = wl->raster + WR_MAX_WIDTH*((WR_MAX_HEIGHT-h)/2) +
 
934
        (WR_MAX_WIDTH-w)/2;
 
935
        curr += xo + WR_MAX_WIDTH * yo; // variation
 
936
 
 
937
        rbyte=(w+7)>>3;
 
938
 
 
939
        for(i=0,dist=0; i < h;i++,curr += WR_MAX_WIDTH,r+=fullByte)
 
940
        {
 
941
                for(j=jj=0;j<rbyte;j++)
 
942
                {
 
943
                        cbyte=r[j];
 
944
                        if(cbyte == 0) {jj+=8;continue;}
 
945
 
 
946
                        for(cc=128;cc;cc>>=1,jj++)
 
947
                        {
 
948
                                if( cbyte & cc )
 
949
                                {
 
950
                                        if( curr[jj] < 0 )
 
951
                                        dist+=2;
 
952
                                }
 
953
                                else
 
954
                                if( curr[jj] > 0 ) dist++;
 
955
                        } // end cc
 
956
 
 
957
                        if( dist > porog ) return dist;
 
958
                } // end j
 
959
        } // end i
 
960
 
 
961
        return (dist);
981
962
}
982
963
 
983
964
///////////////////////
984
 
static int AddTestRecogCollection( BYTE *rast,int xbit,int yrow,
985
 
                int num,RECRESULT *recres,
986
 
                welet *wl,int numWel )
 
965
static int AddTestRecogCollection( uchar *rast,int xbit,int yrow,
 
966
                int num,RECRESULT *recres,
 
967
                welet *wl,int numWel )
987
968
{
988
 
 int rbyte=(xbit+7)>>3;
989
 
 int straf[16];
990
 
 int iSame,i,best,j;
991
 
 RECRESULT recTmp;
 
969
        int rbyte=(xbit+7)>>3;
 
970
        int straf[16];
 
971
        int iSame,i,best,j;
 
972
        RECRESULT recTmp;
992
973
 
993
974
        if(num <= 1)
994
 
                return num;
 
975
        return num;
995
976
 
996
977
        if(recres[0].prob < 250)
997
 
                return num;
 
978
        return num;
998
979
 
999
980
        if(recres[1].prob < recres[0].prob)
1000
 
                return num;
 
981
        return num;
1001
982
 
1002
983
        for(iSame=0,best=0;iSame<num;iSame++)
1003
984
        {
1004
985
                if(iSame >= 16)
1005
 
                        break;
 
986
                break;
1006
987
                if(recres[iSame].prob < recres[0].prob)
1007
 
                     break;
 
988
                break;
1008
989
                straf[iSame]= DistToWeletReal(rast,rbyte,xbit,yrow,
1009
 
                            wl+recres[iSame].nClust, 0,0,100);
 
990
                                wl+recres[iSame].nClust, 0,0,100);
1010
991
                if(straf[iSame] < straf[best])
1011
 
                        best=iSame;
 
992
                best=iSame;
1012
993
        }
1013
994
 
1014
995
        for(i=0;i<iSame;i++)
1015
996
        {
1016
997
                straf[i]-=straf[best];
1017
998
                if(straf[i]>30)
1018
 
              straf[i]=30;
 
999
                straf[i]=30;
1019
1000
                if(straf[i]<recres[i].prob)
1020
 
                        recres[i].prob-=straf[i];
 
1001
                recres[i].prob-=straf[i];
1021
1002
                else
1022
 
                        recres[i].prob=1;
 
1003
                recres[i].prob=1;
1023
1004
        }
1024
1005
 
1025
1006
        // not optimal !!!
1027
1008
        {
1028
1009
                for(j=i+1;j<iSame;j++)
1029
1010
                {
1030
 
                 if(recres[i].prob < recres[j].prob)
1031
 
                 {
1032
 
           recTmp=recres[i];
1033
 
                   recres[i]=recres[j];
1034
 
                   recres[j]=recTmp;
1035
 
                   break;
1036
 
                 }
 
1011
                        if(recres[i].prob < recres[j].prob)
 
1012
                        {
 
1013
                                recTmp=recres[i];
 
1014
                                recres[i]=recres[j];
 
1015
                                recres[j]=recTmp;
 
1016
                                break;
 
1017
                        }
1037
1018
                }
1038
1019
                if(j>=iSame)
1039
 
                        i++;
 
1020
                i++;
1040
1021
                // else - new recres[i]
1041
1022
        }
1042
1023
 
1043
1024
        for(i=iSame;i<num;i++)
1044
 
                recres[i].prob=MIN(recres[i].prob,recres[iSame-1].prob-1);
 
1025
        recres[i].prob=MIN(recres[i].prob,recres[iSame-1].prob-1);
1045
1026
 
1046
1027
        return num;
1047
1028
}
1051
1032
// for handprinted recognition
1052
1033
/////////////////
1053
1034
//
1054
 
// �� ���������� ����� �� ���������� <= bound
 
1035
// не штрафовать точки на расстоянии <= bound
1055
1036
//
1056
1037
#define STRAF_NOTFAR 2
1057
1038
#define STRAF_FAR    4
1058
1039
#define STRAF_CLUFAR 1
1059
1040
 
1060
 
static int distOkr1(PBYTE r,int w,int h,welet * wl,
1061
 
                                   int xo,int yo,int porog,int bound)
1062
 
{
1063
 
PCHAR curr;
1064
 
int   i,j,jj;
1065
 
BYTE  cbyte,cc;
1066
 
int rbyte;
1067
 
int dist1,dist2;
1068
 
int dist;
1069
 
 
1070
 
 dist1 = wl->summa/wl->fill;
1071
 
 dist1*=bound;
1072
 
 if( dist1 > 127) dist1=127;
1073
 
 
1074
 
 // not-weighted distance
1075
 
 if(dist1 < 64 ) dist2 =dist1*2;
1076
 
 else dist2=127;
1077
 
 
1078
 
 dist1=-dist1;
1079
 
 dist2=-dist2;
1080
 
 
1081
 
 curr = wl->raster + WR_MAX_WIDTH*((WR_MAX_HEIGHT-h)/2) +
1082
 
                                  (WR_MAX_WIDTH-w)/2;
1083
 
 curr += xo + WR_MAX_WIDTH * yo; // variation
1084
 
 
1085
 
 rbyte=(w+7)>>3;
1086
 
 
1087
 
 for(i=0,dist=0; i < h;i++,curr += WR_MAX_WIDTH,r+=rbyte)
1088
 
 {
1089
 
  for(j=jj=0;j<rbyte;j++)
1090
 
  {
1091
 
   cbyte=r[j];
1092
 
   if(cbyte == 0) {jj+=8;continue;}
1093
 
 
1094
 
   for(cc=128;cc;cc>>=1,jj++)
1095
 
   {
1096
 
    if( cbyte & cc )
 
1041
static int distOkr1(puchar r, int w, int h, welet * wl, int xo, int yo,
 
1042
                int porog, int bound) {
 
1043
        pchar curr;
 
1044
        int i, j, jj;
 
1045
        uchar cbyte, cc;
 
1046
        int rbyte;
 
1047
        int dist1, dist2;
 
1048
        int dist;
 
1049
 
 
1050
        dist1 = wl->summa / wl->fill;
 
1051
        dist1 *= bound;
 
1052
        if (dist1 > 127)
 
1053
                dist1 = 127;
 
1054
 
 
1055
        // not-weighted distance
 
1056
        if (dist1 < 64)
 
1057
                dist2 = dist1 * 2;
 
1058
        else
 
1059
                dist2 = 127;
 
1060
 
 
1061
        dist1 = -dist1;
 
1062
        dist2 = -dist2;
 
1063
 
 
1064
        curr = wl->raster + WR_MAX_WIDTH * ((WR_MAX_HEIGHT - h) / 2)
 
1065
                        + (WR_MAX_WIDTH - w) / 2;
 
1066
        curr += xo + WR_MAX_WIDTH * yo; // variation
 
1067
 
 
1068
        rbyte = (w + 7) >> 3;
 
1069
 
 
1070
        for (i = 0, dist = 0; i < h; i++, curr += WR_MAX_WIDTH, r += rbyte) {
 
1071
                for (j = jj = 0; j < rbyte; j++) {
 
1072
                        cbyte = r[j];
 
1073
                        if (cbyte == 0) {
 
1074
                                jj += 8;
 
1075
                                continue;
 
1076
                        }
 
1077
 
 
1078
                        for (cc = 128; cc; cc >>= 1, jj++) {
 
1079
                                if (cbyte & cc) {
 
1080
                                        if (curr[jj] < dist2)
 
1081
                                                dist += STRAF_FAR;
 
1082
                                        else if (curr[jj] < dist1)
 
1083
                                                dist += STRAF_NOTFAR;
 
1084
                                }
 
1085
                        } // end cc
 
1086
 
 
1087
                        if (dist > porog)
 
1088
                                return dist;
 
1089
                } // end j
 
1090
        } // end i
 
1091
 
 
1092
        return (dist);
 
1093
}
 
1094
 
 
1095
///////////////////////
 
1096
///////////////////////
 
1097
//
 
1098
// штрафуем точки cluster's
 
1099
//
 
1100
int16_t distOkr2(puchar r, int w, int h, welet * wl, int xo, int yo, int porog,
 
1101
                int proc) {
 
1102
        int16_t ww = wl->w, hh = wl->h;
 
1103
        pchar curr;
 
1104
        int16_t i, j;
 
1105
        uchar cbyte, cc;
 
1106
        int16_t rbyte;
 
1107
        int dist;
 
1108
        int startx = (WR_MAX_WIDTH - w) / 2;
 
1109
        int starty = (WR_MAX_HEIGHT - h) / 2;
 
1110
        int stx = (WR_MAX_WIDTH - ww) / 2; // start cluster
 
1111
        int sty = (WR_MAX_HEIGHT - hh) / 2;
 
1112
        int wei;
 
1113
        int lasty, lastx;
 
1114
        uchar initCC;
 
1115
        uchar *rr;
 
1116
 
 
1117
        wei = wl->weight;
 
1118
        wei = (wei * proc) / 100;
 
1119
 
 
1120
        startx += xo;
 
1121
        starty += yo; // variation
 
1122
        rbyte = (w + 7) >> 3;
 
1123
 
 
1124
        curr = wl->raster + sty * WR_MAX_WIDTH;
 
1125
        dist = 0;
 
1126
 
 
1127
        // add upper lines
 
1128
        for (i = sty; i < starty; i++, curr += WR_MAX_WIDTH)
 
1129
                for (j = stx; j < stx + ww; j++)
 
1130
                        if (curr[j] > wei)
 
1131
                                dist++;
 
1132
        if (dist > porog)
 
1133
                return dist;
 
1134
 
 
1135
        lasty = MIN(starty + h, sty + hh);
 
1136
        lastx = MIN(startx + w, stx + ww);
 
1137
        if (starty < sty)
 
1138
                r += (sty - starty) * rbyte;
 
1139
 
 
1140
        if (startx < stx) {
 
1141
                initCC = 128 >> ((stx - startx) & 7);
 
1142
                r += (stx - startx) >> 3;
 
1143
        } else
 
1144
                initCC = 128; // from first bit
 
1145
 
 
1146
        // now - start inside frame
 
1147
        for (; i < lasty; i++, curr += WR_MAX_WIDTH, r += rbyte) {
 
1148
                for (j = stx; j < startx; j++)
 
1149
                        if (curr[j] > wei)
 
1150
                                dist++;
 
1151
                if (dist > porog)
 
1152
                        return dist;
 
1153
 
 
1154
                cc = initCC;
 
1155
                rr = r;
 
1156
                cbyte = *rr;
 
1157
                for (; j < lastx; j++, cc >>= 1) {
 
1158
                        if (cc == 0) {
 
1159
                                cc = 128;
 
1160
                                cbyte = *(++rr);
 
1161
                        }
 
1162
                        if (((cbyte & cc) == 0) && curr[j] > wei)
 
1163
                                dist++;
 
1164
                } // end j
 
1165
                if (dist > porog)
 
1166
                        return dist;
 
1167
 
 
1168
                // last points in row
 
1169
                for (; j < stx + ww; j++)
 
1170
                        if (curr[j] > wei)
 
1171
                                dist++;
 
1172
                if (dist > porog)
 
1173
                        return dist;
 
1174
        } // end i
 
1175
 
 
1176
        // add down lines
 
1177
        for (; i < sty + hh; i++, curr += WR_MAX_WIDTH)
 
1178
                for (j = stx; j < stx + ww; j++)
 
1179
                        if (curr[j] > wei)
 
1180
                                dist++;
 
1181
 
 
1182
        return (dist);
 
1183
}
 
1184
///////////////
 
1185
static int distOneOkr(puchar r, puchar razmaz, int w, int h, int porog,
 
1186
                welet * wel, int x, int y, int bound, int proc) {
 
1187
        int dist, j;
 
1188
 
 
1189
        dist = distOkr1(r, w, h, wel, x, y, porog - 1, bound);
 
1190
        if (dist >= porog)
 
1191
                return dist;
 
1192
 
 
1193
        j = distOkr2(razmaz, w + 2, h + 2, wel, x, y, porog - dist - 1, proc);
 
1194
 
 
1195
        return dist + j;
 
1196
}
 
1197
///////////////////////////
 
1198
 
 
1199
static int distWeletOkr(uchar *buf, uchar *razmaz, int w, int h, welet * wl,
 
1200
                int porog, int okr, int proc) {
 
1201
        uint16_t best, east, west, north, south, center;
 
1202
        int lbest; // local best
 
1203
        int bound = 200; //2*MIN(50,w+h);
 
1204
        int initPorog = porog;
 
1205
        int ne, es, sw, wn;
 
1206
 
 
1207
        best = east = west = north = south = center = lbest = 0;
 
1208
 
 
1209
        // center - special threshold??? check !!!
 
1210
        center = best = distOneOkr(buf, razmaz, w, h, bound, wl, 0, 0, okr, proc);
 
1211
        // center =best=distOne(buf,bufraz,w,h,porog,wl,0,0);
 
1212
        if (best == 0)
 
1213
                return best;
 
1214
 
 
1215
        // test - if very bad, go away ... !!!
 
1216
        // if(best >= bound ) return porog+1;
 
1217
 
 
1218
        if (best < porog)
 
1219
                porog = best;
 
1220
 
 
1221
        if ((south = distOneOkr(buf, razmaz, w, h, porog, wl, 0, 1, okr, proc))
 
1222
                        < best)
 
1223
                best = south;
 
1224
        if (best == 0)
 
1225
                return best;
 
1226
        if (best < porog)
 
1227
                porog = best;
 
1228
        if ((north = distOneOkr(buf, razmaz, w, h, porog, wl, 0, -1, okr, proc))
 
1229
                        < best)
 
1230
                best = north;
 
1231
        if (best == 0)
 
1232
                return best;
 
1233
        if (best < porog)
 
1234
                porog = best;
 
1235
        if ((east = distOneOkr(buf, razmaz, w, h, porog, wl, 1, 0, okr, proc))
 
1236
                        < best)
 
1237
                best = east;
 
1238
        if (best == 0)
 
1239
                return best;
 
1240
        if (best < porog)
 
1241
                porog = best;
 
1242
        if ((west = distOneOkr(buf, razmaz, w, h, porog, wl, -1, 0, okr, proc))
 
1243
                        < best)
 
1244
                best = west;
 
1245
 
 
1246
        if (best == 0)
 
1247
                return best;
 
1248
        if (best < porog)
 
1249
                porog = best;
 
1250
 
 
1251
        // if(best < north && best < south && best < east && best < west)
 
1252
        //       return best;
 
1253
 
 
1254
        // nothing good ?
 
1255
        if (best >= initPorog) {
 
1256
                north = south = east = west = best;
 
1257
                //       return best;
 
1258
        } else if (best < north && best < south && best < east && best < west)
 
1259
                return best;
 
1260
 
 
1261
        center = best; // to save old best for compare
 
1262
        // where try move ? - now two positions may be
 
1263
        ne = es = sw = wn = 0;
 
1264
 
 
1265
        if (north == center || east == center) {
 
1266
                if ((lbest = distOneOkr(buf, razmaz, w, h, porog, wl, 1, -1, okr, proc))
 
1267
                                < best) {
 
1268
                        best = lbest;
 
1269
                        ne = 1;
 
1270
                        if (best < porog)
 
1271
                                porog = best;
 
1272
                }
 
1273
        }
 
1274
        if (east == center || south == center) {
 
1275
                if ((lbest = distOneOkr(buf, razmaz, w, h, porog, wl, 1, 1, okr, proc))
 
1276
                                < best) {
 
1277
                        best = lbest;
 
1278
                        if (best < porog)
 
1279
                                porog = best;
 
1280
                        ne = 0;
 
1281
                        es = 1;
 
1282
                }
 
1283
        }
 
1284
        if (south == center || west == center) {
 
1285
                if ((lbest = distOneOkr(buf, razmaz, w, h, porog, wl, -1, 1, okr, proc))
 
1286
                                < best) {
 
1287
                        best = lbest;
 
1288
                        if (best < porog)
 
1289
                                porog = best;
 
1290
                        ne = es = 0;
 
1291
                        sw = 1;
 
1292
                }
 
1293
        }
 
1294
        if (west == center || north == center) {
 
1295
                if ((lbest
 
1296
                                = distOneOkr(buf, razmaz, w, h, porog, wl, -1, -1, okr, proc))
 
1297
                                < best) {
 
1298
                        best = lbest;
 
1299
                        wn = 1;
 
1300
                        ne = es = sw = 0;
 
1301
                }
 
1302
        }
 
1303
 
1097
1304
        {
1098
 
                if( curr[jj] < dist2 )
1099
 
                        dist+=STRAF_FAR;
1100
 
        else if( curr[jj] < dist1 )
1101
 
                        dist+=STRAF_NOTFAR;
 
1305
                int movX = 0, movY = 0;
 
1306
                if (ne) {
 
1307
                        movX = 2;
 
1308
                        movY = -2;
 
1309
                } else if (es) {
 
1310
                        movX = 2;
 
1311
                        movY = 2;
 
1312
                } else if (sw) {
 
1313
                        movX = -2;
 
1314
                        movY = 2;
 
1315
                } else if (wn) {
 
1316
                        movX = -2;
 
1317
                        movY = -2;
 
1318
                } else if (south == best)
 
1319
                        movY = 2;
 
1320
                else if (north == best)
 
1321
                        movY = -2;
 
1322
                else if (east == best)
 
1323
                        movX = 2;
 
1324
                else if (west == best)
 
1325
                        movX = -2;
 
1326
 
 
1327
                if ((lbest = distOneOkr(buf, razmaz, w, h, porog, wl, movX, movY, okr,
 
1328
                                proc)) < best)
 
1329
                        best = lbest;
1102
1330
        }
1103
 
   } // end cc
1104
 
 
1105
 
   if( dist > porog )
1106
 
           return dist;
1107
 
  }  // end j
1108
 
 }   // end i
1109
 
 
1110
 
  return (dist);
1111
 
}
1112
 
 
1113
 
///////////////////////
1114
 
///////////////////////
1115
 
//
1116
 
// �������� ����� cluster's
1117
 
//
1118
 
SINT distOkr2(PBYTE r,int  w,int  h,welet * wl,
1119
 
                          int  xo,int  yo, int porog,int proc)
1120
 
{
1121
 
SINT ww=wl->w, hh=wl->h;
1122
 
PCHAR curr;
1123
 
SINT i,j;
1124
 
BYTE  cbyte,cc;
1125
 
SINT rbyte;
1126
 
int dist;
1127
 
int startx=(WR_MAX_WIDTH-w)/2;
1128
 
int starty=(WR_MAX_HEIGHT-h)/2;
1129
 
int stx=(WR_MAX_WIDTH-ww)/2;   // start cluster
1130
 
int sty=(WR_MAX_HEIGHT-hh)/2;
1131
 
int wei;
1132
 
int lasty,lastx;
1133
 
BYTE initCC;
1134
 
BYTE *rr;
1135
 
 
1136
 
  wei= wl->weight;
1137
 
  wei=(wei*proc)/100;
1138
 
 
1139
 
 
1140
 
 startx += xo;
1141
 
 starty += yo; // variation
1142
 
 rbyte=(w+7)>>3;
1143
 
 
1144
 
 curr = wl->raster+sty*WR_MAX_WIDTH;
1145
 
 dist=0;
1146
 
 
1147
 
    // add upper lines
1148
 
 for(i=sty;i<starty;i++,curr+=WR_MAX_WIDTH)
1149
 
     for(j=stx;j<stx+ww;j++)   if(curr[j]> wei) dist++;
1150
 
 if(dist > porog) return dist;
1151
 
 
1152
 
 lasty=MIN(starty+h,sty+hh);
1153
 
 lastx=MIN(startx+w,stx+ww);
1154
 
 if( starty < sty) r+=(sty-starty)*rbyte;
1155
 
 
1156
 
 if(startx < stx)
1157
 
 {initCC=128>>((stx-startx)&7);
1158
 
  r+=(stx-startx)>>3;
1159
 
 }
1160
 
 else initCC=128;   // from first bit
1161
 
 
1162
 
   // now - start inside frame
1163
 
 for(; i < lasty;i++,curr +=WR_MAX_WIDTH,r+=rbyte)
1164
 
 {
1165
 
  for(j=stx;j<startx;j++) if(curr[j] > wei ) dist++;
1166
 
  if(dist > porog ) return dist;
1167
 
 
1168
 
  cc=initCC;
1169
 
  rr=r;
1170
 
  cbyte=*rr;
1171
 
  for(;j<lastx;j++,cc>>=1)
1172
 
  {
1173
 
   if(cc==0) {cc=128;cbyte=*(++rr);}
1174
 
   if( ((cbyte & cc)==0) && curr[j]>wei  ) dist++;
1175
 
  }  // end j
1176
 
  if(dist > porog) return dist;
1177
 
 
1178
 
   // last points in row
1179
 
  for(;j<stx+ww;j++) if(curr[j] > wei ) dist++;
1180
 
  if(dist > porog) return dist;
1181
 
 }   // end i
1182
 
 
1183
 
// add down lines
1184
 
  for(;i<sty+hh;i++,curr+=WR_MAX_WIDTH)
1185
 
     for(j=stx;j<stx+ww;j++)   if(curr[j]> wei) dist++;
1186
 
 
1187
 
  return (dist);
1188
 
}
1189
 
///////////////
1190
 
static int distOneOkr(PBYTE r,PBYTE razmaz,int w,int h,int porog,welet * wel,
1191
 
                                           int x,int y,int bound,int proc)
1192
 
{
1193
 
int dist,j;
1194
 
 
1195
 
  dist=distOkr1(r,w,h,wel,x,y,porog-1,bound);
1196
 
  if(dist >= porog) return dist;
1197
 
 
1198
 
  j= distOkr2(razmaz,w+2,h+2,wel,x,y,porog-dist-1,proc);
1199
 
 
1200
 
  return dist+j;
1201
 
}
1202
 
///////////////////////////
1203
 
 
1204
 
static int distWeletOkr(BYTE *buf,BYTE *razmaz,int w,int h,welet * wl,int porog,int okr,int proc)
1205
 
{
1206
 
 WORD best,east,west,north,south,center;
1207
 
 int   lbest;   // local best
1208
 
 int bound=200; //2*MIN(50,w+h);
1209
 
 int initPorog=porog;
1210
 
 int ne,es,sw,wn;
1211
 
 
1212
 
 best=east=west=north=south=center=lbest=0;
1213
 
 
1214
 
// center - special threshold??? check !!!
1215
 
 center =best=distOneOkr(buf,razmaz,w,h,bound,wl,0,0,okr,proc);
1216
 
// center =best=distOne(buf,bufraz,w,h,porog,wl,0,0);
1217
 
 if(best == 0 ) return best;
1218
 
 
1219
 
 // test - if very bad, go away ... !!!
1220
 
 // if(best >= bound ) return porog+1;
1221
 
 
1222
 
 if(best < porog) porog=best;
1223
 
 
1224
 
 if((south = distOneOkr(buf,razmaz,w,h,porog,wl, 0, 1,okr,proc)) < best )
1225
 
    best = south;
1226
 
 if(best==0) return best;
1227
 
 if(best < porog) porog=best;
1228
 
 if((north = distOneOkr(buf,razmaz,w,h,porog,wl, 0,-1,okr,proc)) < best )
1229
 
   best = north;
1230
 
 if(best==0) return best;
1231
 
 if(best < porog) porog=best;
1232
 
 if((east = distOneOkr(buf,razmaz,w,h,porog,wl, 1, 0,okr,proc)) < best )
1233
 
    best = east;
1234
 
 if(best==0) return best;
1235
 
 if(best < porog) porog=best;
1236
 
 if((west = distOneOkr(buf,razmaz,w,h,porog,wl,-1, 0,okr,proc)) < best )
1237
 
    best = west;
1238
 
 
1239
 
 if(best==0) return best;
1240
 
 if(best < porog) porog=best;
1241
 
 
1242
 
// if(best < north && best < south && best < east && best < west)
1243
 
//       return best;
1244
 
 
1245
 
 // nothing good ?
1246
 
 if( best >= initPorog)
1247
 
 {
1248
 
         north=south=east=west=best;
1249
 
//       return best;
1250
 
 }
1251
 
 else if(best < north && best < south && best < east && best < west)
1252
 
         return best;
1253
 
 
1254
 
 center=best;  // to save old best for compare
1255
 
 // where try move ? - now two positions may be
1256
 
 ne=es=sw=wn=0;
1257
 
 
1258
 
 if( north == center || east == center )
1259
 
 {
1260
 
  if((lbest = distOneOkr(buf,razmaz,w,h,porog,wl,1,-1,okr,proc)) < best )
1261
 
  {
1262
 
    best = lbest;
1263
 
        ne=1;
1264
 
        if(best < porog) porog=best;
1265
 
  }
1266
 
 }
1267
 
 if(east == center || south == center )
1268
 
 {
1269
 
  if((lbest = distOneOkr(buf,razmaz,w,h,porog,wl,1, 1,okr,proc)) < best )
1270
 
  {
1271
 
    best = lbest;
1272
 
        if(best < porog) porog=best;
1273
 
        ne=0;
1274
 
        es=1;
1275
 
  }
1276
 
 }
1277
 
 if(south == center || west == center)
1278
 
 {
1279
 
  if((lbest = distOneOkr(buf,razmaz,w,h,porog,wl,-1, 1,okr,proc)) < best )
1280
 
  {
1281
 
    best = lbest;
1282
 
        if(best < porog) porog=best;
1283
 
        ne=es=0;
1284
 
        sw=1;
1285
 
  }
1286
 
 }
1287
 
 if( west == center || north == center)
1288
 
 {
1289
 
  if((lbest = distOneOkr(buf,razmaz,w,h,porog,wl,-1,-1,okr,proc)) < best )
1290
 
  {
1291
 
    best = lbest;
1292
 
        wn=1;
1293
 
        ne=es=sw=0;
1294
 
  }
1295
 
 }
1296
 
 
1297
 
 {
1298
 
  int movX=0,movY=0;
1299
 
  if( ne )   { movX=2; movY=-2;}
1300
 
  else if(es) { movX=2; movY=2;}
1301
 
  else if(sw) { movX=-2; movY=2;}
1302
 
  else if(wn) { movX=-2; movY=-2;}
1303
 
  else if( south == best ) movY=2;
1304
 
  else if( north == best ) movY=-2;
1305
 
  else if( east == best ) movX=2;
1306
 
  else if( west == best ) movX=-2;
1307
 
 
1308
 
  if((lbest = distOneOkr(buf,razmaz,w,h,porog,wl,movX,movY,okr,proc)) < best )
1309
 
    best = lbest;
1310
 
 }
1311
 
 return best;
1312
 
}
1313
 
 
1314
 
///////////////////////////
1315
 
///////////////////////////
1316
 
// 0xba - ����������� ��� i � ���������� ������
 
1331
        return best;
 
1332
}
 
1333
 
 
1334
///////////////////////////
 
1335
///////////////////////////
 
1336
// 0xba - обозначение для i с приклееной точкой
1317
1337
//static const char Palki[]="!1Iil\xba";
1318
1338
/////////////////
1319
 
static int LookBestOkr(int w,int h,BYTE *buf,BYTE *razmaz,
1320
 
                      int NumClus, int porog,welet *wel,
1321
 
            RECRESULT *recres,int maxNames,int nInCTB,
1322
 
                        int col,int row,int okr,int proc)
1323
 
{
1324
 
 int i,j;
1325
 
 int dist;
1326
 
 int num=0;
1327
 
 
1328
 
 for(i=num=0 ;i<NumClus;i++,wel++)
1329
 
 {
1330
 
  if( wel->invalid ) continue;
1331
 
  if( !(wel->attr & FON_CLU_SOLID)  ) continue;
1332
 
 
1333
 
  // �� ������������ ���� ?
1334
 
  if( wel->weight == 1 &&
1335
 
          (wel->nInCTB ==nInCTB ||
1336
 
           //wel->sr_col == col && wel->sr_row==row
1337
 
           abs(col-wel->sr_col)<=1 && abs(row-wel->sr_row)<=1
1338
 
          )
1339
 
        )
1340
 
//        wel-> work < 230 )
1341
 
          continue;
1342
 
//   dist=(255 - wel->work + 4)/(2*STRAFPOINT) ;
1343
 
 
1344
 
  if( wel->num < 0 )  // �� �� ������ ��������
1345
 
           continue;
1346
 
 
1347
 
  // check for height likeness
1348
 
  j=abs(wel->mh-h);
1349
 
  if( j > 2 && j*3 >  MAX(h,wel->mh)  )
1350
 
           continue;
1351
 
 
1352
 
  j=abs(wel->mw-w);
1353
 
  if( j > 3 && j*3 >= MAX(w,wel->mw) )
1354
 
          continue;
1355
 
 
1356
 
  dist=distWeletOkr(buf,razmaz,w,h,wel,porog+1,okr,proc);
1357
 
 
1358
 
  if(dist <= porog)
1359
 
  { num=AddVersion( recres,(BYTE)wel->let,(BYTE)(255-dist),i,
1360
 
                    num,maxNames);
1361
 
    if(num>=maxNames)
1362
 
         {porog=255-recres[maxNames-1].prob-1;
1363
 
          if(porog < 0) break;
1364
 
         }
1365
 
//      if(dist==0) break;
1366
 
  }
1367
 
 
1368
 
 }
1369
 
 
1370
 
 return num;
 
1339
static int LookBestOkr(int w, int h, uchar *buf, uchar *razmaz, int NumClus,
 
1340
                int porog, welet *wel, RECRESULT *recres, int maxNames, int nInCTB,
 
1341
                int col, int row, int okr, int proc) {
 
1342
        int i, j;
 
1343
        int dist;
 
1344
        int num = 0;
 
1345
 
 
1346
        for (i = num = 0; i < NumClus; i++, wel++) {
 
1347
                if (wel->invalid)
 
1348
                        continue;
 
1349
                if (!(wel->attr & FON_CLU_SOLID))
 
1350
                        continue;
 
1351
 
 
1352
                // не распознавать себя ?
 
1353
                if (wel->weight == 1 && (wel->nInCTB == nInCTB ||
 
1354
                //wel->sr_col == col && wel->sr_row==row
 
1355
                                abs(col - wel->sr_col) <= 1 && abs(row - wel->sr_row) <= 1))
 
1356
                        //        wel-> work < 230 )
 
1357
                        continue;
 
1358
                //   dist=(255 - wel->work + 4)/(2*STRAFPOINT) ;
 
1359
 
 
1360
                if (wel->num < 0) // не из нашего алфавита
 
1361
                        continue;
 
1362
 
 
1363
                // check for height likeness
 
1364
                j = abs(wel->mh - h);
 
1365
                if (j > 2 && j * 3 > MAX(h, wel->mh))
 
1366
                        continue;
 
1367
 
 
1368
                j = abs(wel->mw - w);
 
1369
                if (j > 3 && j * 3 >= MAX(w, wel->mw))
 
1370
                        continue;
 
1371
 
 
1372
                dist = distWeletOkr(buf, razmaz, w, h, wel, porog + 1, okr, proc);
 
1373
 
 
1374
                if (dist <= porog) {
 
1375
                        num = AddVersion(recres, (uchar) wel->let, (uchar)(255 - dist), i,
 
1376
                                        num, maxNames);
 
1377
                        if (num >= maxNames) {
 
1378
                                porog = 255 - recres[maxNames - 1].prob - 1;
 
1379
                                if (porog < 0)
 
1380
                                        break;
 
1381
                        }
 
1382
                        //      if(dist==0) break;
 
1383
                }
 
1384
 
 
1385
        }
 
1386
 
 
1387
        return num;
1371
1388
}
1372
1389
 
1373
1390
///////////////////////
1374
 
int RecogCluOkr(BYTE *rast,SINT xbyte,SINT xbit,SINT yrow,
1375
 
              RECRESULT *recres, SINT maxNames,
1376
 
              welet *wl,int numWel,
1377
 
              int porog ,int nInCTB, Int16 col, Int16 row,
1378
 
                          int okr,int proc)
1379
 
{
1380
 
 int i;
1381
 
 int rbyte=(xbit+7)>>3;
1382
 
 BYTE *b1;
1383
 
 BYTE hvost=mask0[xbit&7];
1384
 
 
1385
 
 
1386
 
 if(wl==NULL || numWel <= 0) return 0;
1387
 
 if(xbyte*yrow > REC_MAX_RASTER_SIZE) yrow=REC_MAX_RASTER_SIZE/xbyte;
1388
 
 
1389
 
 for(i=0,b1=buf;i<yrow;i++,b1+=rbyte,rast+=xbyte)
1390
 
 {
1391
 
         memcpy(b1,rast,rbyte);
1392
 
         b1[rbyte-1]&=hvost;
1393
 
 }
1394
 
 
1395
 
  Razmaz2(buf,bufrazmaz,xbit,yrow,0,POROG_ANGLES);
1396
 
 
1397
 
  //porog=MAX(xbit,yrow);
1398
 
  if(porog < 0) porog= 200;
1399
 
 
1400
 
  if(maxNames > MAX_ALT )
1401
 
              maxNames=MAX_ALT;
1402
 
  i=LookBestOkr(xbit,yrow,buf,bufrazmaz,
1403
 
                      numWel,porog,wl,recres, maxNames,nInCTB,col,row,okr,proc);
1404
 
 
1405
 
  return i;
1406
 
}
1407
 
///////////////////////////
1408
 
int CompareClusterOkr(BYTE *rast,int xbyte,int xbit,int yrow,welet *wel,
1409
 
                                   int movex,int movey,int okr,int proc,
1410
 
                                   int *dist1,int *dist2)
1411
 
{
1412
 
 int i;
1413
 
 int rbyte=(xbit+7)>>3;
1414
 
 BYTE *b1;
1415
 
 BYTE hvost=mask0[xbit&7];
1416
 
 
1417
 
 if( wel==NULL ) return 0;
1418
 
 if(xbyte*yrow > REC_MAX_RASTER_SIZE) yrow=REC_MAX_RASTER_SIZE/xbyte;
1419
 
 
1420
 
 // to static buffer
1421
 
 for(i=0,b1=buf;i<yrow;i++,b1+=rbyte,rast+=xbyte)
1422
 
 {memcpy(b1,rast,rbyte);
1423
 
  b1[rbyte-1]&=hvost;
1424
 
 }
1425
 
 Razmaz2(buf,bufrazmaz,(SINT)xbit,(SINT)yrow,0,POROG_ANGLES);
1426
 
 
1427
 
 i=distOneOkr(buf,bufrazmaz,xbit,yrow,250,wel,movex,movey,okr,proc);
1428
 
 *dist1=distOkr1(buf,xbit,yrow,wel,movex,movey,250,okr);
1429
 
 *dist2 =distOkr2(bufrazmaz,xbit+2,yrow+2,wel,movex,movey,250,proc);
1430
 
 return 255-i;
1431
 
}
1432
 
///////////////////////////
1433
 
// ������� ����� �������
1434
 
static int distOkr(PBYTE r,int w,int h,welet * wl,
1435
 
                                   int xo,int yo,int porog)
1436
 
{
1437
 
PCHAR curr;
1438
 
int   i,j,jj;
1439
 
BYTE  cbyte,cc;
1440
 
int rbyte;
1441
 
int dist;
1442
 
 
1443
 
 curr = wl->raster + WR_MAX_WIDTH*((WR_MAX_HEIGHT-h)/2) +
1444
 
                                  (WR_MAX_WIDTH-w)/2;
1445
 
 curr += xo + WR_MAX_WIDTH * yo; // variation
1446
 
 
1447
 
 rbyte=(w+7)>>3;
1448
 
 
1449
 
 for(i=0,dist=0; i < h;i++,curr += WR_MAX_WIDTH,r+=rbyte)
1450
 
 {
1451
 
  for(j=jj=0;j<rbyte;j++)
1452
 
  {
1453
 
   cbyte=r[j];
1454
 
   if(cbyte == 0) {jj+=8;continue;}
1455
 
 
1456
 
   for(cc=128;cc;cc>>=1,jj++)
1457
 
   {
1458
 
    if( cbyte & cc )
1459
 
        {
1460
 
                if( curr[jj] < 0 )
1461
 
                        dist++;
1462
 
        }
1463
 
   } // end cc
1464
 
 
1465
 
   if( dist > porog )
1466
 
           return dist;
1467
 
  }  // end j
1468
 
 }   // end i
1469
 
 
1470
 
  return (dist);
 
1391
int RecogCluOkr(uchar *rast, int16_t xbyte, int16_t xbit, int16_t yrow,
 
1392
                RECRESULT *recres, int16_t maxNames, welet *wl, int numWel, int porog,
 
1393
                int nInCTB, int16_t col, int16_t row, int okr, int proc) {
 
1394
        int i;
 
1395
        int rbyte = (xbit + 7) >> 3;
 
1396
        uchar *b1;
 
1397
        uchar hvost = mask0[xbit & 7];
 
1398
 
 
1399
        if (wl == NULL || numWel <= 0)
 
1400
                return 0;
 
1401
        if (xbyte * yrow > REC_MAX_RASTER_SIZE)
 
1402
                yrow = REC_MAX_RASTER_SIZE / xbyte;
 
1403
 
 
1404
        for (i = 0, b1 = buf; i < yrow; i++, b1 += rbyte, rast += xbyte) {
 
1405
                memcpy(b1, rast, rbyte);
 
1406
                b1[rbyte - 1] &= hvost;
 
1407
        }
 
1408
 
 
1409
        Razmaz2(buf, bufrazmaz, xbit, yrow, 0, POROG_ANGLES);
 
1410
 
 
1411
        //porog=MAX(xbit,yrow);
 
1412
        if (porog < 0)
 
1413
                porog = 200;
 
1414
 
 
1415
        if (maxNames > MAX_ALT)
 
1416
                maxNames = MAX_ALT;
 
1417
        i = LookBestOkr(xbit, yrow, buf, bufrazmaz, numWel, porog, wl, recres,
 
1418
                        maxNames, nInCTB, col, row, okr, proc);
 
1419
 
 
1420
        return i;
 
1421
}
 
1422
///////////////////////////
 
1423
int CompareClusterOkr(uchar *rast, int xbyte, int xbit, int yrow, welet *wel,
 
1424
                int movex, int movey, int okr, int proc, int *dist1, int *dist2) {
 
1425
        int i;
 
1426
        int rbyte = (xbit + 7) >> 3;
 
1427
        uchar *b1;
 
1428
        uchar hvost = mask0[xbit & 7];
 
1429
 
 
1430
        if (wel == NULL)
 
1431
                return 0;
 
1432
        if (xbyte * yrow > REC_MAX_RASTER_SIZE)
 
1433
                yrow = REC_MAX_RASTER_SIZE / xbyte;
 
1434
 
 
1435
        // to static buffer
 
1436
        for (i = 0, b1 = buf; i < yrow; i++, b1 += rbyte, rast += xbyte) {
 
1437
                memcpy(b1, rast, rbyte);
 
1438
                b1[rbyte - 1] &= hvost;
 
1439
        }
 
1440
        Razmaz2(buf, bufrazmaz, (int16_t) xbit, (int16_t) yrow, 0, POROG_ANGLES);
 
1441
 
 
1442
        i = distOneOkr(buf, bufrazmaz, xbit, yrow, 250, wel, movex, movey, okr,
 
1443
                        proc);
 
1444
        *dist1 = distOkr1(buf, xbit, yrow, wel, movex, movey, 250, okr);
 
1445
        *dist2 = distOkr2(bufrazmaz, xbit + 2, yrow + 2, wel, movex, movey, 250,
 
1446
                        proc);
 
1447
        return 255 - i;
 
1448
}
 
1449
///////////////////////////
 
1450
// сколько точек вылазит
 
1451
static int distOkr(puchar r, int w, int h, welet * wl, int xo, int yo,
 
1452
                int porog) {
 
1453
        pchar curr;
 
1454
        int i, j, jj;
 
1455
        uchar cbyte, cc;
 
1456
        int rbyte;
 
1457
        int dist;
 
1458
 
 
1459
        curr = wl->raster + WR_MAX_WIDTH * ((WR_MAX_HEIGHT - h) / 2)
 
1460
                        + (WR_MAX_WIDTH - w) / 2;
 
1461
        curr += xo + WR_MAX_WIDTH * yo; // variation
 
1462
 
 
1463
        rbyte = (w + 7) >> 3;
 
1464
 
 
1465
        for (i = 0, dist = 0; i < h; i++, curr += WR_MAX_WIDTH, r += rbyte) {
 
1466
                for (j = jj = 0; j < rbyte; j++) {
 
1467
                        cbyte = r[j];
 
1468
                        if (cbyte == 0) {
 
1469
                                jj += 8;
 
1470
                                continue;
 
1471
                        }
 
1472
 
 
1473
                        for (cc = 128; cc; cc >>= 1, jj++) {
 
1474
                                if (cbyte & cc) {
 
1475
                                        if (curr[jj] < 0)
 
1476
                                                dist++;
 
1477
                                }
 
1478
                        } // end cc
 
1479
 
 
1480
                        if (dist > porog)
 
1481
                                return dist;
 
1482
                } // end j
 
1483
        } // end i
 
1484
 
 
1485
        return (dist);
1471
1486
}
1472
1487
 
1473
1488
///////////////////////
1474
1489
//#define KOEFF 4
1475
 
static int LookBestInner(int w,int h,BYTE *buf,BYTE *razmaz,
1476
 
                    int NumClus, welet *wel,
1477
 
            RECRESULT *recres,int maxNames,int nInCTB,
1478
 
                        Int16 *col,Int16 *row)
1479
 
{
1480
 
 int i,j,k;
1481
 
 int dist;
1482
 
 int num=0;
1483
 
 int x,y;
1484
 
 int porog;
1485
 
 int dists[9];
1486
 
 int best;
1487
 
 int startx,starty;
1488
 
 int stepx,stepy;
1489
 
 int lastx,lasty;
1490
 
 int brow,bcol;
1491
 
 float KOEFF=MAX(1.0f,(w*h)/250.0f);
1492
 
 
1493
 
 for(i=num=0 ;i<NumClus;i++,wel++)
1494
 
 {
1495
 
  if( wel->invalid ) continue;
1496
 
  if( !(wel->attr & FON_CLU_SOLID)  ) continue;
1497
 
 
1498
 
  // �� ������������ ���� ?
1499
 
 
1500
 
  if( wel->num < 0 )  // �� �� ������ ��������
1501
 
           continue;
1502
 
 
1503
 
  if( wel->mh*2 < h ||
1504
 
          wel->mw*2 < w
1505
 
    )
1506
 
        continue;
1507
 
 
1508
 
  porog = 240;
 
1490
static int LookBestInner(int w, int h, uchar *buf, uchar *razmaz, int NumClus,
 
1491
                welet *wel, RECRESULT *recres, int maxNames, int nInCTB, int16_t *col,
 
1492
                int16_t *row) {
 
1493
        int i, j, k;
 
1494
        int dist;
 
1495
        int num = 0;
 
1496
        int x, y;
 
1497
        int porog;
 
1498
        int dists[9];
 
1499
        int best;
 
1500
        int startx, starty;
 
1501
        int stepx, stepy;
 
1502
        int lastx, lasty;
 
1503
        int brow, bcol;
 
1504
        float KOEFF = MAX(1.0f, (w * h) / 250.0f);
 
1505
 
 
1506
        for (i = num = 0; i < NumClus; i++, wel++) {
 
1507
                if (wel->invalid)
 
1508
                        continue;
 
1509
                if (!(wel->attr & FON_CLU_SOLID))
 
1510
                        continue;
 
1511
 
 
1512
                // не распознавать себя ?
 
1513
 
 
1514
                if (wel->num < 0) // не из нашего алфавита
 
1515
                        continue;
 
1516
 
 
1517
                if (wel->mh * 2 < h || wel->mw * 2 < w)
 
1518
                        continue;
 
1519
 
 
1520
                porog = 240;
1509
1521
 
1510
1522
#ifdef _NOT_ALL_
1511
 
  best=-1;
1512
 
  for(k=0;k<9;k++)
1513
 
          dists[k]=porog;
1514
 
 
1515
 
  for(y=-1,k=0;y<=1;y++)
1516
 
  {
1517
 
   for(x=-1;x<=1;x++,k++)
1518
 
   {
1519
 
    dist=(int)(distOkr(buf,w,h,wel,x,y,(int)(porog*KOEFF))/KOEFF);
1520
 
    if(dist >= porog)
1521
 
          continue;
1522
 
    j = distOkr2(razmaz,w+2,h+2,wel,x,y,porog-dist,30);
1523
 
        dist += j;
1524
 
 
1525
 
        dists[k]=dist;
1526
 
 
1527
 
        if( dist < porog )
1528
 
        {
1529
 
                porog = dist;
1530
 
                best=k;
1531
 
                brow=y;
1532
 
                bcol=x;
1533
 
                if( porog == 0 ) break;
1534
 
        }
1535
 
   }
1536
 
  }
1537
 
 
1538
 
  if( porog == 0 )
1539
 
           goto addvers;
1540
 
 
1541
 
  switch(best)
1542
 
  {
1543
 
   case 0:
1544
 
           startx=starty=-2;
1545
 
           stepx=stepy=-1;
1546
 
       lastx=lasty=-5;
1547
 
           break;
1548
 
   case 1:
1549
 
           startx=-2;
1550
 
           starty=-2;
1551
 
           stepx=1;
1552
 
           stepy=-1;
1553
 
       lastx= 3;
1554
 
           lasty=-5;
1555
 
           break;
1556
 
   case 2:
1557
 
           startx=2;
1558
 
           starty=-2;
1559
 
           stepx=1;
1560
 
           stepy=-1;
1561
 
       lastx= 5;
1562
 
           lasty=-5;
1563
 
           break;
1564
 
   case 3:
1565
 
           startx=-2;
1566
 
           starty=-2;
1567
 
           stepx = -1;
1568
 
           stepy = 1;
1569
 
       lastx = -5;
1570
 
           lasty = 3;
1571
 
           break;
1572
 
   case 4: goto addvers;
1573
 
   case 5:
1574
 
           startx=2;
1575
 
           starty=-2;
1576
 
           stepx=1;
1577
 
           stepy= 1;
1578
 
       lastx= 5;
1579
 
           lasty= 3;
1580
 
           break;
1581
 
   case 6:
1582
 
           startx=-2;
1583
 
           starty= 2;
1584
 
           stepx = -1;
1585
 
           stepy = 1;
1586
 
       lastx = -5;
1587
 
           lasty = 5;
1588
 
           break;
1589
 
   case 7:
1590
 
           startx=-2;
1591
 
           starty= 2;
1592
 
           stepx = 1;
1593
 
           stepy = 1;
1594
 
       lastx = 3;
1595
 
           lasty = 5;
1596
 
           break;
1597
 
   case 8:
1598
 
           startx= 2;
1599
 
           starty= 2;
1600
 
           stepx = 1;
1601
 
           stepy = 1;
1602
 
       lastx = 5;
1603
 
           lasty = 5;
1604
 
           break;
1605
 
   default:
1606
 
           continue;
1607
 
  }
 
1523
                best = -1;
 
1524
                for (k = 0; k < 9; k++)
 
1525
                        dists[k] = porog;
 
1526
 
 
1527
                for (y = -1, k = 0; y <= 1; y++) {
 
1528
                        for (x = -1; x <= 1; x++, k++) {
 
1529
                                dist = (int) (distOkr(buf, w, h, wel, x, y, (int) (porog
 
1530
                                                * KOEFF)) / KOEFF);
 
1531
                                if (dist >= porog)
 
1532
                                        continue;
 
1533
                                j = distOkr2(razmaz, w + 2, h + 2, wel, x, y, porog - dist, 30);
 
1534
                                dist += j;
 
1535
 
 
1536
                                dists[k] = dist;
 
1537
 
 
1538
                                if (dist < porog) {
 
1539
                                        porog = dist;
 
1540
                                        best = k;
 
1541
                                        brow = y;
 
1542
                                        bcol = x;
 
1543
                                        if (porog == 0)
 
1544
                                                break;
 
1545
                                }
 
1546
                        }
 
1547
                }
 
1548
 
 
1549
                if (porog == 0)
 
1550
                        goto addvers;
 
1551
 
 
1552
                switch (best) {
 
1553
                case 0:
 
1554
                        startx = starty = -2;
 
1555
                        stepx = stepy = -1;
 
1556
                        lastx = lasty = -5;
 
1557
                        break;
 
1558
                case 1:
 
1559
                        startx = -2;
 
1560
                        starty = -2;
 
1561
                        stepx = 1;
 
1562
                        stepy = -1;
 
1563
                        lastx = 3;
 
1564
                        lasty = -5;
 
1565
                        break;
 
1566
                case 2:
 
1567
                        startx = 2;
 
1568
                        starty = -2;
 
1569
                        stepx = 1;
 
1570
                        stepy = -1;
 
1571
                        lastx = 5;
 
1572
                        lasty = -5;
 
1573
                        break;
 
1574
                case 3:
 
1575
                        startx = -2;
 
1576
                        starty = -2;
 
1577
                        stepx = -1;
 
1578
                        stepy = 1;
 
1579
                        lastx = -5;
 
1580
                        lasty = 3;
 
1581
                        break;
 
1582
                case 4:
 
1583
                        goto addvers;
 
1584
                case 5:
 
1585
                        startx = 2;
 
1586
                        starty = -2;
 
1587
                        stepx = 1;
 
1588
                        stepy = 1;
 
1589
                        lastx = 5;
 
1590
                        lasty = 3;
 
1591
                        break;
 
1592
                case 6:
 
1593
                        startx = -2;
 
1594
                        starty = 2;
 
1595
                        stepx = -1;
 
1596
                        stepy = 1;
 
1597
                        lastx = -5;
 
1598
                        lasty = 5;
 
1599
                        break;
 
1600
                case 7:
 
1601
                        startx = -2;
 
1602
                        starty = 2;
 
1603
                        stepx = 1;
 
1604
                        stepy = 1;
 
1605
                        lastx = 3;
 
1606
                        lasty = 5;
 
1607
                        break;
 
1608
                case 8:
 
1609
                        startx = 2;
 
1610
                        starty = 2;
 
1611
                        stepx = 1;
 
1612
                        stepy = 1;
 
1613
                        lastx = 5;
 
1614
                        lasty = 5;
 
1615
                        break;
 
1616
                default:
 
1617
                        continue;
 
1618
                }
1608
1619
#else
1609
 
       startx= -4;
1610
 
           starty= -4;
1611
 
           stepx = 1;
1612
 
           stepy = 1;
1613
 
       lastx = 5;
1614
 
           lasty = 5;
 
1620
                startx= -4;
 
1621
                starty= -4;
 
1622
                stepx = 1;
 
1623
                stepy = 1;
 
1624
                lastx = 5;
 
1625
                lasty = 5;
1615
1626
#endif
1616
1627
 
1617
 
  for(x=startx;x!=lastx;x+=stepx)
1618
 
  {
1619
 
   for(y=starty;y!=lasty;y+=stepy)
1620
 
   {
1621
 
    dist=(int)(distOkr(buf,w,h,wel,x,y,(int)(porog*KOEFF))/KOEFF);
1622
 
    if(dist >= porog)
1623
 
          continue;
1624
 
    j = distOkr2(razmaz,w+2,h+2,wel,x,y,porog-dist,30);
1625
 
        dist += j;
1626
 
        if( dist < porog )
1627
 
        {
1628
 
                porog = dist;
1629
 
                brow=y;
1630
 
                bcol=x;
1631
 
                if( porog == 0 ) break;
 
1628
                for (x = startx; x != lastx; x += stepx) {
 
1629
                        for (y = starty; y != lasty; y += stepy) {
 
1630
                                dist = (int) (distOkr(buf, w, h, wel, x, y, (int) (porog
 
1631
                                                * KOEFF)) / KOEFF);
 
1632
                                if (dist >= porog)
 
1633
                                        continue;
 
1634
                                j = distOkr2(razmaz, w + 2, h + 2, wel, x, y, porog - dist, 30);
 
1635
                                dist += j;
 
1636
                                if (dist < porog) {
 
1637
                                        porog = dist;
 
1638
                                        brow = y;
 
1639
                                        bcol = x;
 
1640
                                        if (porog == 0)
 
1641
                                                break;
 
1642
                                }
 
1643
                        }
 
1644
                        if (porog == 0)
 
1645
                                break;
 
1646
                } //  end x
 
1647
 
 
1648
                addvers: if (porog >= 240)
 
1649
                        continue;
 
1650
 
 
1651
                if (num <= 0 || recres[0].prob < 255 - porog) {
 
1652
                        *row = brow;
 
1653
                        *col = bcol;
 
1654
                }
 
1655
 
 
1656
                num = AddVersion(recres, (uchar) wel->let, (uchar)(255 - porog), i,
 
1657
                                num, maxNames);
 
1658
 
1632
1659
        }
1633
 
   }
1634
 
   if( porog == 0 )
1635
 
           break;
1636
 
  } //  end x
1637
 
 
1638
 
addvers:
1639
 
  if( porog >= 240 )
1640
 
          continue;
1641
 
 
1642
 
  if( num <= 0 || recres[0].prob < 255-porog )
1643
 
  {
1644
 
          *row=brow;
1645
 
          *col=bcol;
1646
 
  }
1647
 
 
1648
 
  num=AddVersion( recres,(BYTE)wel->let,(BYTE)(255-porog),i,
1649
 
                    num,maxNames);
1650
 
 
1651
 
 
1652
 
 }
1653
 
 
1654
 
 return num;
 
1660
 
 
1661
        return num;
1655
1662
}
1656
1663
///////////////////////
1657
 
static int ScaleSymbol(BYTE *inbuf,int fullByte,int allSizeX, int allSizeY,BYTE *outbuf,int newX,int newY);
1658
 
 
1659
 
 
1660
 
int RecogCluInner(BYTE *rast,SINT xbyte,SINT xbit,SINT yrow,
1661
 
              RECRESULT *recres, SINT maxNames,
1662
 
              welet *wl,int numWel,
1663
 
              int nInCTB, Int16 *col, Int16 *row )
1664
 
{
1665
 
 int i;
1666
 
 int rbyte=(xbit+7)>>3;
1667
 
 BYTE *b1;
1668
 
 BYTE hvost=mask0[xbit&7];
1669
 
 Bool32 needCopy=TRUE;
1670
 
 
1671
 
 
1672
 
 if(wl==NULL || numWel <= 0)
1673
 
         return 0;
1674
 
 if( xbit <= 0 || yrow <= 0 )
1675
 
         return 0;
1676
 
 
1677
 
 if(xbyte*yrow > REC_MAX_RASTER_SIZE)
1678
 
         yrow=REC_MAX_RASTER_SIZE/xbyte;
 
1664
static int ScaleSymbol(uchar *inbuf, int fullByte, int allSizeX, int allSizeY,
 
1665
                uchar *outbuf, int newX, int newY);
 
1666
 
 
1667
int RecogCluInner(uchar *rast, int16_t xbyte, int16_t xbit, int16_t yrow,
 
1668
                RECRESULT *recres, int16_t maxNames, welet *wl, int numWel, int nInCTB,
 
1669
                int16_t *col, int16_t *row) {
 
1670
        int i;
 
1671
        int rbyte = (xbit + 7) >> 3;
 
1672
        uchar *b1;
 
1673
        uchar hvost = mask0[xbit & 7];
 
1674
        Bool32 needCopy = TRUE;
 
1675
 
 
1676
        if (wl == NULL || numWel <= 0)
 
1677
                return 0;
 
1678
        if (xbit <= 0 || yrow <= 0)
 
1679
                return 0;
 
1680
 
 
1681
        if (xbyte * yrow > REC_MAX_RASTER_SIZE)
 
1682
                yrow = REC_MAX_RASTER_SIZE / xbyte;
1679
1683
 
1680
1684
#ifdef _NEED_SCALE_
1681
 
 // need scale ?
1682
 
 if( *col > 0 || *row > 0 )
1683
 
 {
1684
 
    int newX=*col,newY=*row;
 
1685
        // need scale ?
 
1686
        if( *col > 0 || *row > 0 )
 
1687
        {
 
1688
                int newX=*col,newY=*row;
1685
1689
 
1686
 
        if( newY <= 0 )
 
1690
                if( newY <= 0 )
1687
1691
                newY = (yrow*newX)/xbit;
1688
1692
 
1689
 
        if( newY <= 0)
 
1693
                if( newY <= 0)
1690
1694
                return 0;
1691
1695
 
1692
 
// our symbol inside full frame must be STANDARD_HEIGHT
1693
 
// STANDARD_WIDTH - don't use
1694
 
        newX = (xbit*STANDARD_HEIGHT)/newY;
1695
 
        newY = (yrow*STANDARD_HEIGHT)/newY;
 
1696
                // our symbol inside full frame must be STANDARD_HEIGHT
 
1697
                // STANDARD_WIDTH - don't use
 
1698
                newX = (xbit*STANDARD_HEIGHT)/newY;
 
1699
                newY = (yrow*STANDARD_HEIGHT)/newY;
1696
1700
 
1697
 
        if( newX != xbit || newY != yrow )
1698
 
        {
1699
 
     int AddBitmapToSnap(BYTE *buf,int xbit,int yrow,int name,int dist);
1700
 
     i= ScaleSymbol(rast,xbyte,xbit, yrow, buf, newX,newY);
1701
 
         if( i < 0 )
1702
 
                 return i;
1703
 
         needCopy = FALSE;
1704
 
         xbit = newX;
1705
 
         yrow = newY;
1706
 
// to view ...
1707
 
//       AddBitmapToSnap(buf,xbit, yrow,0,newY);
1708
 
//       FONShowSnap();
 
1701
                if( newX != xbit || newY != yrow )
 
1702
                {
 
1703
                        int AddBitmapToSnap(uchar *buf,int xbit,int yrow,int name,int dist);
 
1704
                        i= ScaleSymbol(rast,xbyte,xbit, yrow, buf, newX,newY);
 
1705
                        if( i < 0 )
 
1706
                        return i;
 
1707
                        needCopy = FALSE;
 
1708
                        xbit = newX;
 
1709
                        yrow = newY;
 
1710
                        // to view ...
 
1711
                        //       AddBitmapToSnap(buf,xbit, yrow,0,newY);
 
1712
                        //       FONShowSnap();
 
1713
                }
1709
1714
        }
1710
 
 }
1711
1715
#endif
1712
1716
 
1713
 
 if( needCopy )
1714
 
 {
1715
 
  for(i=0,b1=buf;i<yrow;i++,b1+=rbyte,rast+=xbyte)
1716
 
  {
1717
 
         memcpy(b1,rast,rbyte);
1718
 
         b1[rbyte-1]&=hvost;
1719
 
  }
1720
 
 }
1721
 
 
1722
 
  Razmaz2(buf,bufrazmaz,xbit,yrow,0,POROG_ANGLES);
1723
 
 
1724
 
  if(maxNames > MAX_ALT )
1725
 
              maxNames=MAX_ALT;
1726
 
  i=LookBestInner(xbit,yrow,buf,bufrazmaz,
1727
 
                      numWel,wl,recres, maxNames,nInCTB,col,row);
1728
 
 
1729
 
  return i;
 
1717
        if (needCopy) {
 
1718
                for (i = 0, b1 = buf; i < yrow; i++, b1 += rbyte, rast += xbyte) {
 
1719
                        memcpy(b1, rast, rbyte);
 
1720
                        b1[rbyte - 1] &= hvost;
 
1721
                }
 
1722
        }
 
1723
 
 
1724
        Razmaz2(buf, bufrazmaz, xbit, yrow, 0, POROG_ANGLES);
 
1725
 
 
1726
        if (maxNames > MAX_ALT)
 
1727
                maxNames = MAX_ALT;
 
1728
        i = LookBestInner(xbit, yrow, buf, bufrazmaz, numWel, wl, recres, maxNames,
 
1729
                        nInCTB, col, row);
 
1730
 
 
1731
        return i;
1730
1732
}
1731
1733
///////////////////////////
1732
 
static BYTE *tmpBufScale=NULL;
 
1734
static uchar *tmpBufScale = NULL;
1733
1735
 
1734
 
void EndScale(void)
1735
 
{
1736
 
        if( tmpBufScale )
 
1736
void EndScale(void) {
 
1737
        if (tmpBufScale)
1737
1738
                free(tmpBufScale);
1738
1739
 
1739
1740
        tmpBufScale = NULL;
1740
1741
}
1741
1742
/////////////
1742
 
static int ScaleSymbol(BYTE *inbuf,int fullByte,int allSizeX, int allSizeY,BYTE *outbuf,int newX,int newY)
1743
 
{
1744
 
 int allSize;
1745
 
 int i,j;
1746
 
 BYTE cc;
1747
 
 BYTE *tbuf,*cbuf;
1748
 
 int  bigStep,oneStep;
1749
 
 BYTE *obuf;
1750
 
 int  xbyte;
1751
 
 int  k,kk;
1752
 
 int  summa;
1753
 
 
1754
 
 
1755
 
    if( allSizeX <= 0 || allSizeY <= 0)
 
1743
static int ScaleSymbol(uchar *inbuf, int fullByte, int allSizeX, int allSizeY,
 
1744
                uchar *outbuf, int newX, int newY) {
 
1745
        int allSize;
 
1746
        int i, j;
 
1747
        uchar cc;
 
1748
        uchar *tbuf, *cbuf;
 
1749
        int bigStep, oneStep;
 
1750
        uchar *obuf;
 
1751
        int xbyte;
 
1752
        int k, kk;
 
1753
        int summa;
 
1754
 
 
1755
        if (allSizeX <= 0 || allSizeY <= 0)
1756
1756
                return -1;
1757
1757
 
1758
 
        xbyte=(newX+7)>>3;
1759
 
 
1760
 
    if(xbyte*newY > REC_MAX_RASTER_SIZE)
1761
 
            newY=REC_MAX_RASTER_SIZE/xbyte;
1762
 
 
1763
 
        allSize = allSizeX*newX*allSizeY*newY;
1764
 
        tmpBufScale=realloc(tmpBufScale,allSize);
1765
 
 
1766
 
        if( !tmpBufScale)
 
1758
        xbyte = (newX + 7) >> 3;
 
1759
 
 
1760
        if (xbyte * newY > REC_MAX_RASTER_SIZE)
 
1761
                newY = REC_MAX_RASTER_SIZE / xbyte;
 
1762
 
 
1763
        allSize = allSizeX * newX * allSizeY * newY;
 
1764
        tmpBufScale = realloc(tmpBufScale, allSize);
 
1765
 
 
1766
        if (!tmpBufScale)
1767
1767
                return -2;
1768
1768
 
1769
 
        memset(tmpBufScale,0,allSize);
1770
 
 
1771
 
        bigStep = allSizeX*newX*newY;
1772
 
        oneStep = allSizeX*newX;
1773
 
 
1774
 
        obuf=inbuf;
1775
 
    for(i=0,tbuf=tmpBufScale;i< allSizeY;i++,tbuf+=bigStep,obuf+=fullByte)
1776
 
        {
1777
 
                for(j=0,cc=128;j<allSizeX;j++,cc>>=1)
1778
 
                {
1779
 
                        if(!cc)
1780
 
                           cc=128;
1781
 
                        if( obuf[j>>3]&cc)
1782
 
                        {
1783
 
                                for(k=0,cbuf=tbuf+j*newX;k<newY;k++,cbuf+=oneStep)
1784
 
                                 memset(cbuf,1,newX);
 
1769
        memset(tmpBufScale, 0, allSize);
 
1770
 
 
1771
        bigStep = allSizeX * newX * newY;
 
1772
        oneStep = allSizeX * newX;
 
1773
 
 
1774
        obuf = inbuf;
 
1775
        for (i = 0, tbuf = tmpBufScale; i < allSizeY; i++, tbuf += bigStep, obuf
 
1776
                        += fullByte) {
 
1777
                for (j = 0, cc = 128; j < allSizeX; j++, cc >>= 1) {
 
1778
                        if (!cc)
 
1779
                                cc = 128;
 
1780
                        if (obuf[j >> 3] & cc) {
 
1781
                                for (k = 0, cbuf = tbuf + j * newX; k < newY; k++, cbuf
 
1782
                                                += oneStep)
 
1783
                                        memset(cbuf, 1, newX);
1785
1784
                        }
1786
1785
                }
1787
1786
        }
1788
1787
 
1789
 
        memset(outbuf,0,xbyte*newY);
 
1788
        memset(outbuf, 0, xbyte * newY);
1790
1789
        obuf = outbuf;
1791
1790
 
1792
 
        bigStep = allSizeX*newX*allSizeY;
 
1791
        bigStep = allSizeX * newX * allSizeY;
1793
1792
 
1794
 
        for(i=0,tbuf=tmpBufScale;i< newY;i++,tbuf+=bigStep,obuf+=xbyte)
1795
 
        {
1796
 
                for(j=0,cc=128;j<newX;j++,cc>>=1)
1797
 
                {
1798
 
            if( cc == 0 )
 
1793
        for (i = 0, tbuf = tmpBufScale; i < newY; i++, tbuf += bigStep, obuf
 
1794
                        += xbyte) {
 
1795
                for (j = 0, cc = 128; j < newX; j++, cc >>= 1) {
 
1796
                        if (cc == 0)
1799
1797
                                cc = 128;
1800
1798
 
1801
 
                        cbuf = tbuf + j*allSizeX;
1802
 
            summa = 0;
1803
 
                        for(k=0;k<allSizeY;k++,cbuf+=oneStep)
1804
 
                        {
1805
 
                                for(kk=0;kk<allSizeX;kk++)
1806
 
                                   summa+=cbuf[kk];
 
1799
                        cbuf = tbuf + j * allSizeX;
 
1800
                        summa = 0;
 
1801
                        for (k = 0; k < allSizeY; k++, cbuf += oneStep) {
 
1802
                                for (kk = 0; kk < allSizeX; kk++)
 
1803
                                        summa += cbuf[kk];
1807
1804
                        }
1808
1805
 
1809
 
                        if(summa*2 >= allSizeX*allSizeY )
1810
 
                                obuf[j>>3] |= cc;
 
1806
                        if (summa * 2 >= allSizeX * allSizeY)
 
1807
                                obuf[j >> 3] |= cc;
1811
1808
                }
1812
1809
        }
1813
1810