/*
Copyright (c) 1993-2008, Cognitive Technologies
All rights reserved.

╨рчЁх°рхЄё  яютЄюЁэюх ЁрёяЁюёЄЁрэхэшх ш шёяюы№чютрэшх ъръ т тшфх шёїюфэюую ъюфр,
Єръ ш т фтюшўэющ ЇюЁьх, ё шчьхэхэш ьш шыш схч, яЁш ёюсы■фхэшш ёыхфє■∙шї єёыютшщ:

      * ╧Ёш яютЄюЁэюь ЁрёяЁюёЄЁрэхэшш шёїюфэюую ъюфр фюыцэ√ юёЄртрЄ№ё  єърчрээюх
        т√°х єтхфюьыхэшх юс ртЄюЁёъюь яЁртх, ¤ЄюЄ ёяшёюъ єёыютшщ ш яюёыхфє■∙шщ
        юЄърч юЄ урЁрэЄшщ.
      * ╧Ёш яютЄюЁэюь ЁрёяЁюёЄЁрэхэшш фтюшўэюую ъюфр т фюъєьхэЄрЎшш ш/шыш т
        фЁєушї ьрЄхЁшрырї, яюёЄрты хь√ї яЁш ЁрёяЁюёЄЁрэхэшш, фюыцэ√ ёюїЁрэ Є№ё 
        єърчрээр  т√°х шэЇюЁьрЎш  юс ртЄюЁёъюь яЁртх, ¤ЄюЄ ёяшёюъ єёыютшщ ш
        яюёыхфє■∙шщ юЄърч юЄ урЁрэЄшщ.
      * ═ш эрчтрэшх Cognitive Technologies, эш шьхэр хх ёюЄЁєфэшъют эх ьюуєЄ
        с√Є№ шёяюы№чютрэ√ т ърўхёЄтх ёЁхфёЄтр яюффхЁцъш ш/шыш яЁюфтшцхэш 
        яЁюфєъЄют, юёэютрээ√ї эр ¤Єюь ╧╬, схч яЁхфтрЁшЄхы№эюую яшё№ьхээюую
        ЁрчЁх°хэш .

▌╥└ ╧╨╬├╨└╠╠└ ╧╨┼─╬╤╥└┬╦┼═└ ┬╦└─┼╦▄╓└╠╚ └┬╥╬╨╤╩╚╒ ╧╨└┬ ╚/╚╦╚ ─╨╙├╚╠╚ ╦╚╓└╠╚ "╩└╩
╬═└ ┼╤╥▄" ┴┼╟ ╩└╩╬├╬-╦╚┴╬ ┬╚─└ ├└╨└═╥╚╔, ┬█╨└╞┼══█╒ ▀┬═╬ ╚╦╚ ╧╬─╨└╟╙╠┼┬└┼╠█╒,
┬╩╦▐╫└▀ ├└╨└═╥╚╚ ╩╬╠╠┼╨╫┼╤╩╬╔ ╓┼══╬╤╥╚ ╚ ╧╨╚├╬─═╬╤╥╚ ─╦▀ ╩╬═╩╨┼╥═╬╔ ╓┼╦╚, ═╬ ═┼
╬├╨└═╚╫╚┬└▀╤▄ ╚╠╚. ═╚ ┬╦└─┼╦┼╓ └┬╥╬╨╤╩╚╒ ╧╨└┬ ╚ ═╚ ╬─═╬ ─╨╙├╬┼ ╦╚╓╬, ╩╬╥╬╨╬┼
╠╬╞┼╥ ╚╟╠┼═▀╥▄ ╚/╚╦╚ ╧╬┬╥╬╨═╬ ╨└╤╧╨╬╤╥╨└═▀╥▄ ╧╨╬├╨└╠╠╙, ═╚ ┬ ╩╬┼╠ ╤╦╙╫└┼ ═┼
═┼╤и╥ ╬╥┬┼╥╤╥┬┼══╬╤╥╚, ┬╩╦▐╫└▀ ╦▐┴█┼ ╬┴┘╚┼, ╤╦╙╫└╔═█┼, ╤╧┼╓╚└╦▄═█┼ ╚╦╚
╧╬╤╦┼─╬┬└┬╪╚┼ ╙┴█╥╩╚, ╤┬▀╟└══█┼ ╤ ╚╤╧╬╦▄╟╬┬└═╚┼╠ ╚╦╚ ╧╬═┼╤┼══█┼ ┬╤╦┼─╤╥┬╚┼
═┼┬╬╟╠╬╞═╬╤╥╚ ╚╤╧╬╦▄╟╬┬└═╚▀ ╧╨╬├╨└╠╠█ (┬╩╦▐╫└▀ ╧╬╥┼╨╚ ─└══█╒, ╚╦╚ ─└══█┼,
╤╥└┬╪╚┼ ═┼├╬─═█╠╚, ╚╦╚ ╙┴█╥╩╚ ╚/╚╦╚ ╧╬╥┼╨╚ ─╬╒╬─╬┬, ╧╬═┼╤┼══█┼ ╚╟-╟└ ─┼╔╤╥┬╚╔
╥╨┼╥▄╚╒ ╦╚╓ ╚/╚╦╚ ╬╥╩└╟└ ╧╨╬├╨└╠╠█ ╨└┴╬╥└╥▄ ╤╬┬╠┼╤╥═╬ ╤ ─╨╙├╚╠╚ ╧╨╬├╨└╠╠└╠╚,
═╬ ═┼ ╬├╨└═╚╫╚┬└▀╤▄ ▌╥╚╠╚ ╤╦╙╫└▀╠╚), ═╬ ═┼ ╬├╨└═╚╫╚┬└▀╤▄ ╚╠╚, ─└╞┼ ┼╤╦╚ ╥└╩╬╔
┬╦└─┼╦┼╓ ╚╦╚ ─╨╙├╬┼ ╦╚╓╬ ┴█╦╚ ╚╟┬┼┘┼═█ ╬ ┬╬╟╠╬╞═╬╤╥╚ ╥└╩╚╒ ╙┴█╥╩╬┬ ╚ ╧╬╥┼╨▄.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
    * Neither the name of the Cognitive Technologies nor the names of its
      contributors may be used to endorse or promote products derived from this
      software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/* DIFFR.C : diskrimintion functions for russian language */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "tech.h"
#include "tuner.h"
#include "ligas.h"

#include "status.h"	// 08.09.2000 E.P.
#include "lang_def.h"	// 08.09.2000 E.P.
#include "linutil.h"

#include "compat_defs.h"

uchar broken_flag=0;
uchar rec5_flag=1,font_type=0,omni=1;
static int16_t AngleBottomLeft(uchar *raster,int16_t D_X,int16_t hei);
static int16_t AngleTopLeft(uchar *raster,int16_t D_X,int16_t hei);
static int16_t AngleBottomRight(uchar *raster,int16_t D_X,int16_t hei);
static int16_t AngleTopRight(uchar *raster,int16_t D_X,int16_t hei);
int16_t AnglesCurve(uchar *raster,int16_t D_X,int16_t hei);

#ifdef UFA
static int16_t Diskr5(uchar *raster,int16_t D_X,int16_t hei);
static int16_t Diskr2(uchar *raster,int16_t D_X,int16_t hei);
static int16_t OlegJurit( uchar *R, int16_t D_X, int16_t dy);
static int16_t DiskrHoriz(uchar *R,int16_t D_X,int16_t hei);
#include "Tab_angl.H"
#endif

int16_t  LinesWithNumIntervals(uchar *rastr,int16_t D_X,int16_t dy,int16_t num);
int16_t  NumVertInterval(uchar *RASTER,int16_t D_X, int16_t dy, int16_t i);
int16_t  VertSum(uchar *rastr,int16_t D_X, int16_t dy, int16_t i);
int16_t  SumBits(uchar *rastr,int16_t D_X);
int16_t  NumHorizInterval(uchar *,int16_t);
int16_t  MinMaxRight(uchar *raster,int16_t D_X,uchar dx,
				uchar Ly, int16_t *mi,int16_t *ma);
int16_t  MinMaxLeft (uchar *raster,int16_t D_X,uchar dx,
				uchar Ly, int16_t *mi,int16_t *ma);
int16_t  FOOT(uchar *raster,int16_t DX,uchar dx,uchar Ly,
		uchar sign_filter);
int16_t  FOOT3(uchar *raster,int16_t DX,uchar start,uchar dx,uchar Ly, int16_t SHIFT);
int16_t  FOOT3_2(uchar *raster,int16_t DX,uchar dx,uchar Ly);
int16_t  FOOT_A(uchar *raster,int16_t DX,uchar dx,uchar Ly);
int16_t  Asymm_let(uchar *raster,int16_t DX,uchar dx,
		  uchar Ly,uchar TW);

int16_t  LeftDistance(uchar *RASTER,int16_t dx);
int16_t  RightDistance(uchar *RASTER,int16_t dx);
int16_t  SumIntervalBits(uchar *RASTER,int16_t bx,int16_t ex);
int16_t  CenterVertInterval(uchar *,int16_t ,int16_t ,int16_t, int16_t *,int16_t *);
int16_t  LeftEdgeOfRightmostInt( uchar *rst, int16_t Wdth);
int16_t EndBlackInterval(uchar *RASTER, int16_t NWIDTH);
static int16_t DiskrSymSh( uchar *RASTER, int16_t Wx, uchar NWIDTH, uchar NLENGTH);
static int16_t Diskr9(uchar *rastr,int16_t D_X,int16_t dy,int16_t dx);
static int16_t DiskrLeftBottomHole(uchar *raster,int16_t D_X,int16_t hei,int16_t lim);
static int16_t DiskrRightTopHole(uchar *raster,int16_t D_X,int16_t hei,int16_t lim);
static int16_t LepikJurit( uchar *r,int16_t D_X, int16_t dy);
static int16_t Num2Interval(uchar *r,int16_t D_X,int16_t dx,int16_t dy);
static int16_t broken_M(uchar * r,int16_t D_X,int16_t dy,int16_t ll1, int16_t ll);
static int16_t descr_ce(uchar *r,int16_t D_X,int16_t h);
#ifndef INTERSEPTOR
//static int16_t DiskrJu(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly);
#else
static int16_t DiskrJu1(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly);
#endif
static int16_t Diskr3(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly);
static int16_t DiskrJ0(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly,int16_t lim);
static int DiskrJ(unsigned char *RASTR,int D_X,int dx,int dy);
static int16_t DiskrSh(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly);
static int16_t DiskrLeft(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly, int16_t L);
static int16_t DiskrLeftBig(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly, int16_t L);
static int16_t DiskrRight(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly, int16_t L);
static int16_t DiskrRightBig(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly, int16_t L);
static int16_t DiskrVertCE(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy,int16_t X,uchar l,uchar inc);
static int16_t DiskrSh0(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy,int16_t dx0);
static int16_t DiskrTsh(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy,int16_t Dx);
static void DiskrIN(uchar *RASTR,int16_t D_X,int16_t dy, int16_t wb,int16_t dx);
static int16_t DiskrHorizIN(uchar *RASTR,int16_t D_X,int16_t dy);
static int16_t DiskrEZ(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy);
static int16_t DiskrimM(puchar RAST,int16_t D_X,int16_t dx,int16_t dy);
static int16_t DiskrimM1(uchar *RAST,int16_t D_X,int16_t dx,int16_t dy);
static int16_t whiteMeanBitLeft(uchar *RAST,int16_t D_X,int16_t meanBit);
static int16_t whiteMeanBitRight(uchar *RAST,int16_t D_X,int16_t dx,int16_t meanBit);
static int16_t up_down_hist_M(uchar *rastr,int16_t D_X, int16_t Dx,int16_t dy);
static int16_t average_angle(uchar *RASTER, int16_t D_X, int16_t dx, int16_t dy,
			 int16_t  (*Distance)(uchar *,int16_t),int16_t t);
static int16_t average_tl_angle(uchar *RASTER, int16_t D_X, int16_t dx, int16_t dy,int16_t t);
static int16_t average_bl_angle(uchar *RASTER, int16_t D_X, int16_t dx, int16_t dy,int16_t t);
static int16_t average_br_angle(uchar *RASTER, int16_t D_X, int16_t dx, int16_t dy,int16_t t);
static int16_t NoSymmLastColumn(uchar *raster,int16_t D_X,int16_t Dx,int16_t dy);
int16_t no_serific(uchar *RASTR,int16_t dy,int16_t dx,int16_t wb);
static int16_t fill_center_zone(uchar *raster,int16_t D_X,int16_t dy,
        int16_t beg, int16_t end, int16_t II);
static int16_t up_down_zones(uchar *raster,int16_t D_X,int16_t dx,int16_t dx0,
			int16_t start1,int16_t stop1,
			int16_t start2,int16_t stop2);
static int16_t up_down_zones_for_B(uchar *raster,int16_t D_X,int16_t dx,int16_t dx0,
			int16_t start1,int16_t stop1,
			int16_t start2,int16_t stop2);
static int16_t small_density(uchar *RAST,int16_t n,int16_t D_X,int16_t bw);
static int16_t horiz_density(uchar *RAST,int16_t D_X,int16_t dx,int16_t beg,int16_t end);
#ifdef INTERSEPTOR
static int16_t DiskrVV(uchar *raster,int16_t D_X,int16_t hei);
static int16_t DiskrII(uchar *raster,int16_t D_X,int16_t hei);
#endif

#define bytlen(bits)  ((bits+7)>>3)

extern uchar BUFFER[256];        /* вертикальная   прoекция              */
extern uchar LOCAL[50];        	/* координаты     ног          		*/
extern uchar LOCAL_W[50];      	/* ширины         ног          		*/
extern uchar end1,beg2;        	/* конец 1 и начало 2-ой ног инп	*/
extern broken_ii;		/* флаг двух палок			*/
extern int16_t dnri_hook; // bottom right hook in small russian italic II,III
extern int16_t uple_hook; // bottom left  hook in small russian italic II,III
extern int16_t up_jack  ; // upper jack

static int16_t upper_skip_lines,lower_skip_lines;
static int16_t diskr_g,diskr_sh,diskr_b,diskr_k,diskr_ju,diskr_f2,diskr_tsh,
	diskr_ii,IN_N_Bonus,IN_P_Bonus,IN_I_Bonus,IN_IN_Monus,diskr_N,
    diskr_o,diskr_c,diskr_e,diskr_h,diskr_ja,diskr_z,diskr_ee,diskr_d,
    diskr_ce,IN_dis,diskr_i,diskr_n,diskr_p,IN_equ,IN_N,IN_I,IN_M,IN_pics,
    diskr_m,mii,diskr_tsche,diskr_l,
    diskr_EZ,diskr_B,diskr_E,diskr_y,
    diskr_9,diskr_6,diskr_5,diskr_2,diskr_8;
int16_t left_dist[4], right_dist[4], num_foot, c_or_e,d_c,d_e,
    right_max,left_max,left_line,right_line,
    left_dist_big[4], right_dist_big[4],lower_long_line;
int16_t av_tl, av_bl,av_br, rotate;
/* g-Ж, sh-Ш, b-B, k-K, ju-Ю, f2-ИНП, tsh-Щ, ii-Ы, o-O, c-C, e-E,
   h-Х, ja-Я, z-З, ee-Э, d-Д, ce-Ц  */
int16_t fill_center,up_down_serif,up_down_serif_B,IN_horiz_dis,broken_M_pen;

/*  clear diskrimination flags */
void init_diskrim(puchar raster,int16_t height ,int16_t width)
{
int16_t i, D_X=bytlen(width);
puchar r;

rotate=0;
diskr_g=diskr_sh=diskr_b=diskr_k=diskr_ju=diskr_f2=
diskr_tsh=diskr_ii=diskr_o=diskr_c=diskr_e=diskr_ee=
diskr_9=diskr_5=diskr_6=diskr_2=diskr_8=diskr_N=
diskr_h=diskr_ja=diskr_z=diskr_d=diskr_ce=diskr_l=
left_dist_big[1]= right_dist_big[1]= left_dist[1]= right_dist[1]=
left_dist_big[2]= right_dist_big[2]= left_dist[2]= right_dist[2]=
left_dist_big[3]= right_dist_big[3]= left_dist[3]= right_dist[3]=
num_foot= c_or_e=d_c=d_e=diskr_EZ=
diskr_B=diskr_E=diskr_y=
fill_center=IN_dis=diskr_i=diskr_n=diskr_p=IN_equ=IN_N=IN_I=IN_M=
IN_pics=up_down_serif=up_down_serif_B=IN_horiz_dis=
diskr_m=diskr_tsche=broken_M_pen=
lower_long_line=right_max=left_max=-1;
av_tl=av_bl=av_br=-1;
mii=-101;

IN_N_Bonus=0;
IN_P_Bonus=0;
IN_I_Bonus=0;
IN_IN_Monus=0;

r = raster;
for(  i=0;i<height && SumBits( r ,D_X)<3;i++,r+=D_X);
upper_skip_lines = i;

r = raster + D_X*(height-1);
for(  i=0;i<2 && SumBits( r ,D_X)<3;i++,r-=D_X);
lower_skip_lines = i;

return;
}

/* Diskrim : diskrimination function for diapason 0-255    */
/* PARAMETRS :                                             */
/*	let    - name of letter                            */
/*	raster - bit map( work raster )                    */
/*	D_X    - whidth of bit map( length bit string )    */
/*	X,Y    - coordinats of first point in raster       */
/*	dx,dy  - whidth and height work raster             */
/*							   */
/*   RETURN :   0 - good letter                            */
/*	       >0 - decreasing code                        */

int16_t Diskrim(uchar let,puchar raster,
      int16_t D_X,int16_t X,int16_t Y,int16_t dx,int16_t dy,uchar cg_flag, int16_t inc)
{
int16_t P=0,F=0,Dx,Hy,n,bw;
uchar *rastr,*rastr0;
int16_t d_l, d_r;
#define  step_diskr 20

rotate= (inc>180) ;
if( upper_skip_lines )
	{
	raster += bytlen(D_X)*upper_skip_lines;
	dy-=upper_skip_lines;
	}
if( lower_skip_lines &&
	! (memchr("цЦщЩ",let,4) &&
		!is_russian_turkish_conflict(let) // 21.05.2002 E.P.
	  )
   )
	{
	dy-=lower_skip_lines;
	}

if( dy<8 || dx<3 )
	return(step_diskr*10);

D_X = bytlen(D_X);
Dx = dx + (X&7);
bw = bytlen(Dx);
rastr0= raster + Y*D_X+(X>>3);
rastr = rastr0 + D_X*(dy>>2);
Hy = dy-2*(dy>>2);
d_l = (X&7)+(dx>>2);
d_r = ((bytlen(Dx))<<3)-dx-(X&7)+(dx>>2);

switch( (uchar)let )
	{
  case (uchar)'N' :
		if( diskr_N<0 )
		{
        uchar rasterN[4096];
        int i,ii,iii;

        for(iii=D_X*(dy-1),ii=i=0;i<dy;i++,ii+=D_X,iii-=D_X)
            memcpy(rasterN+iii,raster+ii,D_X);
        rastr0= rasterN + Y*D_X+(X>>3);
        rastr = rastr0 + D_X*(dy>>2);
        F = FOOT(rastr, D_X,(uchar)Dx, (uchar)Hy,1);
		if( F!=2 || MIN(LOCAL_W[0],LOCAL_W[1])>3 && beg2-end1<3 )
			{
			if( dy>13 )
				F=FOOT(rastr0+2*D_X, D_X,(uchar)Dx, (uchar)(dy-4),0);
			else
				F=FOOT(rastr0, D_X,(uchar)Dx, (uchar)dy,0);
			}
		if( F!=2 )
			{
			if( small_density(rastr,Hy,D_X,bw) )
				P = 6*step_diskr;
			else
				P += step_diskr;
                        if( F==3 )
				P +=6*step_diskr;
			}
		   else
		   {
           IN_dis=-1;
		   DiskrIN(rastr0,D_X,dy,bw,dx);
		   IN_dis=-1;
           if( 2*LOCAL[0]>5*LOCAL_W[0] && 2*(dx-LOCAL[1])<3*LOCAL_W[1])
            P += 2*step_diskr;
		   if( IN_I<3 )
			P += MIN(2*(7-IN_I+IN_equ) * step_diskr,160)/2;
		   else if( IN_I==3 && IN_equ>2 )
			P += IN_equ*step_diskr;
		   //if( IN_I>10 && IN_M==0 )
            //P += 40;
		   }

      if( inc>0 )  // OLEG : ERECTION conditions : 09-12-95 07:29pm
        P >>= 1;

		diskr_N = P;
		}
		else P=diskr_N;
        IN_dis=-1;
        IN_IN_Monus=0;
        IN_pics=1;
        IN_M=0;
		break;

  case (uchar)'М' :  case (uchar)'м' :
                if( omni )
                {
                if( diskr_m<0 )
			{
			if( mii<-100 ){
			   if(broken_flag)
			      mii = DiskrimM1(rastr0, D_X, dx, dy );
			   else
			      mii = DiskrimM(rastr0, D_X, dx, dy );
			}
		if(mii>0)
			P+= mii*step_diskr;
		if(mii==0)
			       P+= 5*step_diskr;

		if( dy>13 )
			F=FOOT(rastr0+2*D_X, D_X,(uchar)Dx, (uchar)(dy-4),0);
		else
			F=FOOT(rastr0, D_X,(uchar)Dx, (uchar)dy,0);

                   if( F==2 )
			{
			DiskrIN(rastr0,D_X,dy,bw,dx);
			if( LOCAL[0] > dx/4)
				P >>=2 ;
			P += IN_M;
			}

                        diskr_m = P;
			}
		else  P = diskr_m;
		}
		break;
  case (uchar)'Ы' :  case (uchar)'ы' :
		if( diskr_ii<0 )
      {
			if( omni )
			 {
			 if( mii<-100 )
			    if(broken_flag)
			       mii = DiskrimM1(rastr0, D_X, dx, dy );
			    else
			       mii = DiskrimM(rastr0, D_X, dx, dy );
			    if(mii<0)
				 P += (-mii)*step_diskr;
			    if(mii==0)
				 P+= 5*step_diskr;
			 }
			diskr_ii = P;
			}
		else  P = diskr_ii;
		break;

  case (uchar)'Б' :
	if(omni){
		if( diskr_B<0 )
		   {
		   if( !DiskrRight(rastr0, D_X, Dx, dy,2) )
			P = step_diskr;
		   diskr_B = P;
		   }
		   else P = diskr_B;
		}
		break;
  case (uchar)'Е' :
	if(omni){
		if( diskr_E<0 )
		   {
		   if( !horiz_density(rastr0,D_X,dx,Hy,dy) )
			P = step_diskr;
		   diskr_E = P;
		   }
		   else P = diskr_E;
		}
		break;
  case (uchar)'Д' :  case (uchar)'д' :
		if( diskr_d<0 )
		   {
		   if( average_bl_angle(rastr0,D_X,Dx,dy,0)>d_l )
			P = 4*step_diskr;
		   if( average_br_angle(rastr0,D_X,Dx,dy,0)>d_r )
                        P += 2*step_diskr;
		   if( !horiz_density(rastr0,D_X,dx,Hy,dy) )
			P += step_diskr;
		   diskr_d = P;
		   }
		   else P = diskr_d;
		break;
  case (uchar)'К' :  case (uchar)'к' :
		if( diskr_k<0 )
		   {
                   if( font_type==0  )
		   {              	/* Poly 	*/
		   if( !DiskrRightBig(rastr0, D_X, Dx, dy,2) )
			P=3*step_diskr;
                   // OLEG : ERECTION EFFECT : 09-22-95 07:32pm
                   if( !(rotate && dnri_hook) )
                        {
                        if( DiskrLeft(rastr0, D_X, Dx, dy,2) )
                                P+=3*step_diskr;
                        if( DiskrJ0(rastr, D_X, Dx, Hy,(int16_t)(dy<18?4:5))==0 )
                                P+=5*step_diskr;
                        }
                   else
                      {
                      if( DiskrLeft(rastr0, D_X, Dx, dy,2) )
                        P+=3*step_diskr;
                      }
		   }
		   else
		   {			/* Twrite	*/
		   if( !DiskrRight(rastr0, D_X, Dx, dy,2) )
			P=3*step_diskr;
		   }
		   diskr_k = P;
		   }
		   else P = diskr_k;
		break;
  case (uchar)'В' : /*     case 'в' :*/
#ifdef INTERSEPTOR
  case (uchar)'в' :
#endif
		if( diskr_b<0 )
		   {
#ifdef INTERSEPTOR
       if( DiskrVV(rastr0,D_X,dy)==2 )
        P += 100;
#endif
		   if( !DiskrRight(rastr0, D_X, Dx, dy,1) )
        {    /* нет дырки */
        if( dy<=19 ) /* маленькие 'в' не имеют дырочки */
          {
          if( !omni )
          if( !NoSymmLastColumn(rastr0,D_X,Dx,dy) )
            P+=3*step_diskr;
          }
        else        /* большие должны иметь вмятину */
          {
#ifdef INTERSEPTOR
          if( dy>22 )
          if( !NoSymmLastColumn(rastr0,D_X,Dx,dy) )
#endif
            P+=2*step_diskr;
          }
        }
		   else
        {   /* вмятина есть */
        if( (n=up_down_zones_for_B(rastr0,D_X,Dx,dx,0,(int16_t)(dy>>2),Hy,dy))==1 )
          {
          if( !omni )
            P+=n*2*step_diskr;
          else if( n==2 )
            P+=step_diskr;
          }
       }

		   diskr_b = P;
		   }
		   else P = diskr_b;
		break;
	case '3' :
  case (uchar)'З' :  case (uchar)'з' :
   if( diskr_z<0 )
     {
		   if( !DiskrRight(rastr0, D_X, Dx, dy,1) )
		   {    /* нет дырки */
	 if(dy<14 && DiskrEZ(rastr0, D_X, dx, dy)==1 )
                      P+=step_diskr;
	 else
	    if( (dy<21) ||(cg_flag&16)) /* маленькие 'з' не имеют дырочки */
               {
                if( dy>13 &&(!(cg_flag&16)))
		  if(!NoSymmLastColumn(rastr0,D_X,Dx,dy) )
				P+=3*step_diskr;
	       }
	    else        /* большие должны иметь вмятину */
		P+=2*step_diskr;
       }
#ifdef UFA
    else if( right_max>0 && right_max>=(dx*5)/12 )   // (1/2 + 1/3 ) /2
      P += step_diskr;
		if(  OlegJurit(rastr0,D_X,dy) )
			P += 3*step_diskr;
#endif
		   diskr_z = P;
		   }
		   else P = diskr_z;
		break;

  case (uchar)'Э' :  case (uchar)'э' :

	   // ┬ сюыурЁёъюь эхЄ ▌¤. 08.09.2000 E.P.
	   if (language==PUMA_LANG_RUSSIAN && langBul)
			{P=200;break;}

		if( diskr_ee<0 )
		   {
       if( DiskrRight(rastr0, D_X, (int16_t)((dy<20)?Dx:Dx-1), dy,1) )
			P+=2*step_diskr;

       if( dy>13 && dy<21)
		 if(cg_flag&16) /* cut at right side*/
		   {
		   if (LepikJurit(rastr0,D_X,dy))
			   P+=3*step_diskr+2;
		   }
                 else
		   {
		   if (NoSymmLastColumn(rastr0,D_X,Dx,dy) )
			     P+=2*step_diskr;
                   }
		   if(dy<14 && DiskrEZ(rastr0, D_X, dx, dy)==2 )
			   P+=step_diskr;
		   diskr_ee = P;
		   }
		   else P = diskr_ee;

		break;
       /* case (uchar)'Я' : */     case (uchar)'я' : /*Valdemar 9.03.94*/
		if( diskr_ja<0 )
		   {
		   if( !DiskrLeft(rastr0, D_X, Dx, dy,1) ) P=2*step_diskr;
                   if( !omni )
                   { /* для omni есть дискриминаторы углов */
		   if( average_bl_angle(rastr0,D_X,Dx,dy,1) >=
		       average_tl_angle(rastr0,D_X,Dx,dy,1)  )
			P+=2*step_diskr;
		   }
		   diskr_ja = P;
		   }
		   else P = diskr_ja;
		break;
/*  case '8' :*/
  case (uchar)'Х' :
	   if (is_turkish_language(language)) // 21.05.2002 E.P.
		  break;
  case (uchar)'х' :
		if( diskr_h<0 )
		   {
		   if( !DiskrLeftBig(rastr0, D_X, Dx, dy,1) )
			P+=3*step_diskr;
		   if( !DiskrRightBig(rastr0, D_X, Dx, dy,1) )
			P+=3*step_diskr;

                   if( (n=Diskr3(rastr0+D_X*(dy>>1), D_X, Dx, Hy))!=0 && // down
                        (F=Diskr3(rastr0, D_X, Dx, Hy))!=0 )        // up
                        P +=3*step_diskr; // similar >|<
                   diskr_h = P;
		   }
		   else P = diskr_h;
		break;
  case (uchar)'Ж' :  case (uchar)'ж' :
		if( diskr_g<0 )
		   {
		   if( !DiskrLeftBig(rastr0, D_X, (uchar)Dx, (uchar)dy,2) )
        P+=3*step_diskr;
		   if( !DiskrRightBig(rastr0, D_X, Dx, dy,2) )
        P+=3*step_diskr;
       F = FOOT(rastr, D_X,(uchar)Dx, (uchar)Hy,0);
       if( F!=3 && (n=DiskrJ0(rastr, D_X, Dx, Hy,(int16_t)(dy<18?4:5)))!=0 )
        { /* в средней половине нет 3-частных линий */
        if( !DiskrJ(rastr0, D_X, Dx, dy) )
          P+=2*n*step_diskr;
        }
       if( F!=3 && (n=DiskrJ0(rastr0, D_X, Dx, Hy,(int16_t)(dy<18?2:3)))!=0 )
        { /* в верхней половине нет 3-частных линий */
        if( !DiskrJ(rastr0, D_X, Dx, dy) )
          P+=2*n*step_diskr;
        }
#ifdef INTERSEPTOR
      if( let==(uchar)'ж' && dx>55 )
        P += 160;
#endif
       diskr_g = P;
		   }
		   else P = diskr_g;
		break;
  case (uchar)'Ю' :
  case (uchar)'ю' :
	   if (is_turkish_language(language)) // 21.05.2002 E.P.
		  break;
	   if( diskr_ju<0 )
		   {
#ifdef INTERSEPTOR
         if( (F=DiskrJu1(rastr0, D_X, Dx, dy))!=0)
#endif
       if( DiskrLeft(rastr0, D_X, Dx, dy,2) )
      P += 2*step_diskr;
		   if( DiskrRight(rastr0, D_X, Dx, dy,2) )
      P += 2*step_diskr;
#ifdef INTERSEPTOR
      if( let==(uchar)'ю' && dx>55 )
        P += 160;
#endif
		   diskr_ju = P;
		   }
		   else P = diskr_ju;
		break;
  case (uchar)'Ц' :  case (uchar)'ц' :
		if( diskr_ce<0 )
			{
      if( (F=FOOT(rastr0+2*D_X, D_X,(uchar)Dx, (uchar)Hy,0))!=2 )
				P = 4*step_diskr;
			if( average_br_angle(rastr0,D_X,Dx,dy,0)>d_r+1 )
				P += 4*step_diskr;
      if( !(uple_hook && rotate) )
      if( F==2 && descr_ce(rastr0+(dy-3)*D_X,D_X,(int16_t)(dy/2)) )
				P += 6*step_diskr;
			diskr_ce = P;
			}
		else  P = diskr_ce;
		break;
  case (uchar)'Ш' :  case (uchar)'ш' :
		if( diskr_sh<0 )
		   {
       FOOT(rastr, D_X,(uchar)Dx, (uchar)Hy,0);
       if( rotate ) // OLEG : ERECTION conditions : 09-20-95
        {
        F=FOOT3(rastr, D_X, (uchar)(uple_hook?LOCAL[0]-LOCAL_W[0]/2:0 ),
                            (uchar)(dnri_hook?LOCAL[2]+LOCAL_W[2]/2:Dx), (uchar)Hy,(uchar)(Hy<10?1:2));
        if( F!=3 )
          P  = 10*step_diskr;
        }
      else
        {
        if( (F=FOOT3(rastr, D_X, 0, (uchar)Dx, (uchar)Hy,2))!=3 )
          P  = 10*step_diskr;
        else
          P += (step_diskr>>1)*DiskrSymSh(rastr, D_X, (uchar)Dx, (uchar)Hy);
        }
       if( inc<=0 && !broken_flag && DiskrSh0(rastr0, D_X, Dx, dy, dx)==0 )
        P +=/*4**/step_diskr;
		   F = FOOT(rastr, D_X,(uchar)Dx, (uchar)Hy,0);
       // OLEG : ERECTION conditions : 09-20-95 08:34pm
			 if( inc>0 && dnri_hook )
        {
        if( DiskrSh(rastr, D_X, (int16_t)(LOCAL[2]+LOCAL_W[2]/2), Hy) )
          P += step_diskr;
        }
       else
        {
        if( (n=DiskrSh(rastr, D_X, Dx, Hy))!=0 )
          P += n*step_diskr;
        }
		   if( F!=3  )
        P += 12*step_diskr;
		   if( DiskrLeft(rastr0, D_X, Dx, dy,2) )
        P += step_diskr/2;
		   if( DiskrRight(rastr0, D_X, Dx, dy,2) )
        P += step_diskr/2;
       if( FOOT3_2(rastr0,D_X,(uchar)Dx,(uchar)dy) )
        P += step_diskr*3;
		   diskr_sh = P;
       P=MAX(P,0);
       }
		   else  P = diskr_sh;
		break;

  case (uchar)'П' :  case (uchar)'п' :
		if( diskr_p )
			{
      if( dy>13 )
        F=FOOT(rastr0+2*D_X, D_X,(uchar)Dx, (uchar)(dy-4),0);
      else
        F=FOOT(rastr0, D_X,(uchar)Dx, (uchar)dy,0);
#ifdef UFA
    if( F==1 && broken_flag )
      F = FOOT(rastr, D_X,Dx, Hy,1);
#endif
			if( F!=2 )
				P = 6*step_diskr;
			else
        { // F==2
        if( rotate && (dnri_hook||dy<22&&up_jack>1) )
          fill_center_zone(rastr+D_X*(Hy>>2),D_X,(int16_t)(Hy-(Hy>>2)),end1,beg2,1);
        else
          fill_center_zone(rastr,D_X,Hy,end1,beg2,0);
        {
        int16_t f_c=fill_center;
        DiskrIN(rastr0,D_X,dy,bw,dx);
        if( !(rotate && (dnri_hook||dy<22&&up_jack>1)) )
          f_c = fill_center;
        if( f_c==1 )
          P += 8*step_diskr;
        }
      }

			if( (n=up_down_zones(rastr0,D_X,Dx,dx,0,(int16_t)(dy>>2),Hy,dy))!=0 )
				{
				if( omni )
				{
				if( n!=1 )
					P += 4*step_diskr*n;
				}
				else
				{	/* no omni	*/
				if( !broken_flag || n==2 )
					P += 4*step_diskr*n;
				else
					P += 1*step_diskr;
				}
				}

			if( 	IN_P_Bonus && broken_flag && (broken_ii ||
				!IN_IN_Monus &&
				Num2Interval(rastr0+2*D_X, D_X,Dx, (int16_t)(dy-4))) )
					P =(IN_P_Bonus==2)?-254:-250;

      diskr_p = P;
			}
		else P = diskr_p;
		break;
  case (uchar)'И' :  case (uchar)'и' :
		if( diskr_i<0 )
		{
		F = FOOT(rastr, D_X,(uchar)Dx, (uchar)Hy,1);
		if( F!=2 || MIN(LOCAL_W[0],LOCAL_W[1])>3 && beg2-end1<3 )
			{
			if( dy>13 )
				F=FOOT(rastr0+2*D_X, D_X,(uchar)Dx, (uchar)(dy-4),0);
			else
				F=FOOT(rastr0, D_X,(uchar)Dx, (uchar)dy,0);
			}
		if( F!=2 )
			{
			if( small_density(rastr,Hy,D_X,bw) )
				P = 6*step_diskr;
			else
				P += step_diskr;
                        if( F==3 )
				P +=6*step_diskr;
			}
		   else
		   {
       if( rotate && dnri_hook )
        fill_center_zone(rastr+D_X*(Hy>>2),D_X,(int16_t)(Hy-(Hy>>2)),end1,beg2,0);
      else
        fill_center_zone(rastr,D_X,Hy,end1,beg2,0);
		   DiskrIN(rastr0,D_X,dy,bw,dx);
		   if( fill_center==0 )
			{
			if( broken_flag )
				{
				if( IN_I<=3 || IN_pics==0 )
					P += 2*step_diskr;
				}
			else
				P += 8*step_diskr;
			}
		   if( IN_I<3 )
			P += MIN(2*(7-IN_I+IN_equ) * step_diskr,160)/2;
		   else if( IN_I==3 && IN_equ>2 )
			P += IN_equ*step_diskr;
      if( IN_I>=9 )
        { /* очень негоризонтальная перекладина */
        if( (F=up_down_hist_M(rastr0+D_X, D_X,Dx, (int16_t)(dy-2)))>0 )
          P += F*step_diskr>>2;
        if( LOCAL[1]>(Dx>>1) &&
        broken_M(rastr0+2*D_X, D_X,(int16_t)(dy-4),(int16_t)(LOCAL[0]-LOCAL_W[0]/2),
          (int16_t)(LOCAL[1]-LOCAL_W[1]/2)) )
          P += 4*step_diskr;
        }
		   }
      if( inc>0 )  // OLEG : ERECTION conditions : 09-12-95 07:29pm
        P >>= 1;
      if(     IN_I_Bonus && broken_flag && (broken_ii ||
			!IN_IN_Monus &&
			Num2Interval(rastr0+2*D_X, D_X,Dx, (int16_t)(dy-4))) )
			P =(IN_I_Bonus==2)?-254:-250;
		diskr_i = P;
		}
		else P=diskr_i;
		break;
  case (uchar)'Н' :  case (uchar)'н' :
		if( diskr_n<0 )
		{
		F = FOOT(rastr, D_X,(uchar)Dx, (uchar)Hy,1);
		if( F!=2 || MIN(LOCAL_W[0],LOCAL_W[1])>3 && beg2-end1<3 )
			{
			if( dy>13 )
				F=FOOT(rastr0+2*D_X, D_X,(uchar)Dx, (uchar)(dy-4),0);
			else
				F=FOOT(rastr0, D_X,(uchar)Dx, (uchar)dy,0);
			}
		if( F!=2 )
			P = 6*step_diskr;
		else
		   {
      if( rotate && dnri_hook )
        fill_center_zone(rastr+D_X*(Hy>>2),D_X,(int16_t)(Hy-(Hy>>2)),end1,beg2,0);
      else
        fill_center_zone(rastr,D_X,Hy,end1,beg2,0);
		   DiskrIN(rastr0,D_X,dy,bw,dx);
		   if( DiskrHorizIN(rastr0,D_X,dy) )
			{   /* жирная перекладина */
			IN_N=3;
			IN_I=2;
			}
		   if( fill_center==0 )
			{
			if( broken_flag )
				{
				if( IN_N>=3 || IN_pics==0 )
					P += 2*step_diskr;
				}
			else
				P += 8*step_diskr;
			}

		   if( IN_N>3 )
			P += MIN(IN_N * step_diskr,160)/2;
		   if( DiskrRight(rastr0, D_X, Dx, dy,(int16_t)(dy>22?3:2)) )
			P += 3*step_diskr;
		   if( omni )
			{
			if( LOCAL_W[0]>(LOCAL_W[1]<<1) &&
			(LOCAL_W[1]>1 || LOCAL_W[1]==1 && LOCAL_W[0]>3 ) )
				P += 2*step_diskr;
			}
		   }
    if( IN_N_Bonus && broken_flag && (broken_ii ||
			!IN_IN_Monus &&
			Num2Interval(rastr0+2*D_X, D_X,Dx, (int16_t)(dy-4))) )
			P =(IN_N_Bonus==2)?-254:-250;
		diskr_n = P;
		}
		else P=diskr_n;
		break;


  case '<' :
    if( !DiskrRightBig(rastr0, D_X, Dx, dy, 1) )
			P = 3*step_diskr;
                /*
                DiskrLeft(rastr0, D_X, Dx, dy, 2);
		if( left_line==1 )
			P+=3*step_diskr;
                 */
		break;
	case '>' :
    if( !DiskrLeftBig(rastr0, D_X, Dx, dy, 1) )
			P = 3*step_diskr;
      /*
                DiskrRight(rastr0, D_X, Dx, dy, 2);
		if( right_line==1 )
			P+=3*step_diskr;
       */
		break;
	case '0' :
  case (uchar)'О' :
  case (uchar)'о' :
	    if (is_turkish_language(language)) // 21.05.2002 E.P.
		  break;

		if( diskr_o<0 )
		   {
		   if( DiskrRight(rastr0, D_X, Dx, dy, 2) )
				P = step_diskr;
		   diskr_o = P;
		   }
		   else  P = diskr_o;
		break;
  case (uchar)'С' :  case (uchar)'с' :
		if( diskr_c<0 )
		   {
		   if( !DiskrRight(rastr0, D_X, Dx, dy, 2) )
				P = step_diskr;
                   if( (n=DiskrVertCE(rastr0, D_X, dx, dy, X,(uchar)'с',(uchar)inc))!=0 )
				P+=n*step_diskr;
		   diskr_c = P;
		   }
		   else  P = diskr_c;
		break;
  case (uchar)'е' :
  case (uchar)UKR_e : case (uchar)UKR_E :
		if( diskr_e<0 )
		   {
                   if( (n=DiskrVertCE(rastr0, D_X, dx, dy, X,(uchar)'е',(uchar)inc))>2  )
				P+=(n-2)*step_diskr;
		   diskr_e = P;
		   }
		   else  P = diskr_e;
		break;
  case (uchar)'ч' :
	    if (is_turkish_language(language)) // 21.05.2002 E.P.
		  break;
  case (uchar)'Ч' : case '4' :
		if( diskr_tsche<0 )
		   {
		   if( dy>16 )
			n=FOOT(rastr0+2*D_X, D_X,(uchar)Dx,(uchar)(dy-4),2);
		   else
			n=FOOT(rastr0+D_X, D_X,(uchar)Dx,(uchar)(dy-2),2);

      if( n>1 || let!='4' && n==0 )
        P = 5*step_diskr;
      if( n>0 && LOCAL[0]<(Dx>>1) )
        P += 5*step_diskr;
      /*
      if( n==1 && LOCAL[0]>(Dx>>1) &&
        broken_M(rastr0+2*D_X, D_X,dy-4,LOCAL[0]-LOCAL_W[0]/2,
				LOCAL[0]-LOCAL_W[0]/2) )
        P += 4*step_diskr;
      */
      diskr_tsche = P;
		}
		else  P = diskr_tsche;
		break;
  case (uchar)'Щ' :
	    if (is_turkish_language(language)) // 21.05.2002 E.P.
		  break;
  case (uchar)'щ' :
		if( diskr_tsh<0 )
		   {
       F= ((uchar)let==(uchar)'Щ' )?4:2;
		   if( (F=FOOT(rastr0+F*D_X, D_X,(uchar)Dx,(uchar)Hy,0))!=3 )
        P = 10*step_diskr;
       else
        {
        P += (step_diskr>>1)*DiskrSymSh(rastr, D_X, (uchar)Dx, (uchar)Hy);
        if( DiskrTsh(rastr0+D_X,D_X,dx,dy,Dx)==1 )
          P += 3*step_diskr ;
        }
      if( average_br_angle(rastr0,D_X,Dx,dy,0)>d_r )
        P += 4*step_diskr;
      P=MAX(P,0);
      diskr_tsh = P;
      }
    else  P = diskr_tsh;
		break;
  #ifdef UFA
	case (uchar)'б':
  #endif
	case '6' :
		if( diskr_6<0 )
		{
		if( DiskrLeft(rastr0, D_X, (int16_t)((dy<20)?Dx:Dx-1), dy,2) )
			P = step_diskr;
		if( DiskrLeftBottomHole(rastr,D_X,(int16_t)(dy/2),(int16_t)(dx>>1)) )
			P += 2*step_diskr;
		diskr_6 = P;
		}
		else P = diskr_6;
		break;
	case '9' :
		if( diskr_9<0 )
		{
		if( DiskrRight(rastr0, D_X, (int16_t)((dy<20)?Dx:Dx-1), dy,2) )
			P = 2*step_diskr;

#ifdef UFA
		if( P && AnglesCurve(rastr0,D_X,dy)>2 &&
			DiskrLeftBottomHole(rastr,D_X,dy/2,dx>>1) )
				P = 0;
#endif
		if( Diskr9(rastr,D_X,(int16_t)(dy/2),dx)     )
				P += 2*step_diskr;
		diskr_9 = P;
		}
		else P = diskr_9;
		break;
	case '8' :
		if( diskr_8<0 )
		   {
		   if( !DiskrLeft(rastr0, D_X, Dx, dy,1) )
			P+=2*step_diskr;
		   if( !DiskrRight(rastr0, D_X, Dx, dy,1) )
			P+=2*step_diskr;
		   if( !P && DiskrLeftBottomHole(rastr,D_X,(int16_t)(dy/2),(int16_t)(dx>>1)) )
			P += 2*step_diskr;
		   if( !P && DiskrRightTopHole(rastr,D_X,(int16_t)(dy/2),(int16_t)(dx>>1)) )
			P += 2*step_diskr;
		   diskr_8 = P;
		   }
		   else P = diskr_8;
		break;
    case '5' :
		if( diskr_5<0 )
    {
    if( !DiskrLeftBottomHole(rastr,D_X,(int16_t)(dy/2),(int16_t)(dx/2-((dy<21&&dx<15)?2:0))) )
      P += 2*step_diskr;
    diskr_5 = P;
		}
		else P = diskr_5;
    break;
#ifdef UFA
	case '5' :
		if( diskr_5<0 )
		{
		if( (F=Diskr5(rastr0,D_X,dy))!=0 )
			P = F*2*step_diskr;
		diskr_5 = P;
		}
		else P = diskr_5;
		break;
	case '2' :
		if( diskr_2<0 )
		{
		if( (F=Diskr2(rastr0,D_X,dy))!=0 )
			P = F*2*step_diskr;
		if( DiskrLeftBottomHole(rastr,D_X,dy/2,dx>>1) )
			P += 2*step_diskr;
		diskr_2 = P;
		}
		else P = diskr_2;
		break;
	case (uchar)'Г' :
		if( 	DiskrHoriz(rastr,D_X,dy/2) &&
			(F=FOOT(rastr0+2*D_X, D_X,Dx, Hy,0))!=1 )
				P = 4*step_diskr;
		break;
#endif
	default  : break;
	}

#ifdef UFA
if( 	MaxCurveAngles[(uchar)let] &&
	AnglesCurve(rastr0,D_X,dy)>MaxCurveAngles[(uchar)let] )
		P += 3*step_diskr;
#endif
return(P & 0xFFFE);
}

int16_t Diskr9(uchar *rastr,int16_t D_X,int16_t dy,int16_t dx)
{
int16_t l,r,i,d=dx>>1,num,black;
uchar *rr;
for(rr=rastr,num=i=0;i<dy;i++, rr+=D_X)
	{
	l = LeftDistance(rr,D_X);
	r = RightDistance(rr,D_X)-8+(dx&7);
	black = SumBits(rr,D_X);
	if( black>d )
		num += ( dx-l-r-black<d);
	}

return !num;
}

int16_t DiskrLeftBottomHole(uchar *raster,int16_t D_X,int16_t hei,int16_t lim)
{
int16_t i,pen;
uchar *r;

for(pen=0,r=raster,i=0;i<hei;i++,r+=D_X)
	if( i>hei/4 && LeftDistance(r,D_X)>lim )
		pen++;
return pen>hei/4;
}

int16_t DiskrRightTopHole(uchar *raster,int16_t D_X,int16_t hei,int16_t lim)
{
int16_t i,pen;
uchar *r;

for(pen=0,r=raster,i=0;i<hei;i++,r+=D_X)
	if( i<hei/4 && RightDistance(r,D_X)>lim )
		pen++;

return pen>MIN(4,hei/4);
}

#ifdef UFA

int16_t DiskrHoriz(uchar *R,int16_t D_X,int16_t hei)
{
int16_t i;
uchar *rast=R;

for(i=0;i<hei;i++,rast+=D_X)
	if( NumHorizInterval(rast,D_X)==0 )
		return 0;
return 1;
}
int16_t OlegJurit( uchar *R, int16_t D_X, int16_t dy)
{
  int16_t y2,y4,i,ld,rd, ret;
  uchar *r;

  y2 = dy/2;
  y4 = dy/4;
  for (ld= D_X<<3,rd = i = 0, r = R+D_X*y4; i <y2;  i++ ,r+=D_X )
      {
	ret = LeftEdgeOfRightmostInt (r, D_X);
	if (rd<ret)rd=ret;
	if (ld>ret)ld=ret;
      }
 return rd-ld<3 && dy>24 || rd-ld<5 && dy>30 ;
}


int16_t Diskr5(uchar *raster,int16_t D_X,int16_t hei)
{
int pen=0,inc;

inc = AngleTopRight(raster,D_X,hei);
if( inc>3 || hei<23 && inc>2 ) pen++;

inc = AngleTopLeft(raster,D_X,hei);
if( inc>3 || hei<23 && inc>2 ) pen++;

return pen;
}

int16_t Diskr2(uchar *raster,int16_t D_X,int16_t hei)
{
int inc = AngleBottomLeft(raster,D_X,hei),pen=0;
if( inc>3 || hei<23 && inc>2 ) pen++;
return pen;
}


#endif

#ifdef INTERSEPTOR
int16_t DiskrVV(uchar *raster,int16_t D_X,int16_t hei)
{
int inc = AngleBottomLeft(raster,D_X,hei),pen=0;
if( inc>5 ) pen++;
inc = AngleTopLeft(raster,D_X,hei);
if( inc>5 ) pen++;

return pen;
}

int16_t DiskrII(uchar *raster,int16_t D_X,int16_t hei)
{
int pen=0,inc;

inc = AngleTopRight(raster-2*D_X,D_X,hei);
if( inc>4 ) pen++;

inc = AngleTopLeft(raster-2*D_X,D_X,hei);
if( inc>4 ) pen++;

inc = AngleBottomRight(raster+2*D_X,D_X,hei);
if( inc>4 ) pen++;

inc = AngleBottomLeft(raster+2*D_X,D_X,hei);
if( inc>4 ) pen++;

return pen;
}

#endif

int16_t AngleBottomRight(uchar *raster,int16_t D_X,int16_t hei)
{
int i,old,neue,inc;
uchar *r;

raster += D_X * (hei-2);
hei >>= 2;

old=RightDistance(raster,D_X);
for(inc=0,r=raster-D_X,i=1;i<hei;i++,r-=D_X)
	{
	neue = RightDistance(r,D_X);
	if( neue<old )		inc++;
	if( neue>old )		break;
	old  = neue;
	}
return inc;
}

int16_t AngleTopRight(uchar *raster,int16_t D_X,int16_t hei)
{
int i,old,neue,inc;
uchar *r;

raster += D_X;
hei >>= 2;

old=RightDistance(raster,D_X);
for(inc=0,r=raster+D_X,i=1;i<hei;i++,r+=D_X)
	{
	neue = RightDistance(r,D_X);
	if( neue<old )		inc++;
	if( neue>old )		break;
	old  = neue;
	}
return inc;
}

int16_t AngleBottomLeft(uchar *raster,int16_t D_X,int16_t hei)
{
int i,old,neue,inc;
uchar *r;

raster += D_X * (hei-2);
hei >>= 2;

old=LeftDistance(raster,D_X);
for(inc=0,r=raster-D_X,i=1;i<hei;i++,r-=D_X)
	{
	neue = LeftDistance(r,D_X);
	if( neue<old )		inc++;
	if( neue>old )		break;
	old  = neue;
	}
return inc;
}

int16_t AngleTopLeft(uchar *raster,int16_t D_X,int16_t hei)
{
int i,old,neue,inc;
uchar *r;

raster += D_X;
hei >>= 2;

old=LeftDistance(raster,D_X);
for(inc=0,r=raster+D_X,i=1;i<hei;i++,r+=D_X)
	{
	neue = LeftDistance(r,D_X);
	if( neue<old )		inc++;
	if( neue>old )		break;
	old  = neue;
	}
return inc;
}

int16_t AnglesCurve(uchar *raster,int16_t D_X,int16_t hei)
{
int pen=0,inc;

inc = AngleBottomRight(raster,D_X,hei);
if( inc>3 || hei<23 && inc>2 ) pen++;

inc = AngleBottomLeft(raster,D_X,hei);
if( inc>3 || hei<23 && inc>2 ) pen++;

inc = AngleTopRight(raster,D_X,hei);
if( inc>3 || hei<23 && inc>2 ) pen++;

inc = AngleTopLeft(raster,D_X,hei);
if( inc>3 || hei<23 && inc>2 ) pen++;

return pen;
}

int16_t Num2Interval(uchar *r,int16_t D_X,int16_t dx,int16_t dy)
{
int16_t i,n2,p,d;
d = bytlen(dx);
for(i=1;i<3;i++)
if( 	(p=NumHorizInterval(r-D_X*i,d))==1 &&
	(n2=SumBits(r-D_X*i,d))>dx-2 )
	return(0);
for(n2=i=0;i<dy; i++, r+=D_X )
	{
	p=NumHorizInterval(r,d);
	/*  NumHorizInterval : число интервалов в строке */
	n2 += (p==2 );
	}
return ( n2==dy );
}

/* broken_M : сходство с обломком М без левого копытца */
int16_t broken_M(uchar * r,int16_t D_X,int16_t dy,int16_t left_lim,int16_t ll)
{
int16_t i,old,neue,dest,sign,fc,maxd,incr;
uchar *rr;
if( broken_M_pen>=0 )
	return broken_M_pen;
old=RightDistance(r,D_X);
for(rr=r+D_X,i=1;i<dy;i++,rr+=D_X)
	{
	neue=RightDistance(rr,D_X);
	if( abs(neue-old)>1 )
		return (broken_M_pen=0);/* непрямой правый абрис */
	old=neue;
	}
/* прямой правый абрис */
old=LeftDistance(r,D_X);
dest=old;

for(maxd=fc=sign=incr=0,dest=old,rr=r+D_X,i=1;i<dy;i++,rr+=D_X)
	{
	neue=LeftDistance(rr,D_X);
	if( neue<old )
		{
		if( neue==old-1 )
			{
			if( sign )	return (broken_M_pen=0);
			else		sign=1;
			}
		else
		return(broken_M_pen=0);/* немонотонность левого абриса */
		}
	if( neue>=ll )	fc++;
	if( maxd<neue )
		maxd=neue;
  if( neue>=old  ) incr++;
	old=neue;
	}
dest = neue - dest;		/* скачок монотонного левого абриса */
if( left_lim==ll )
	left_lim=3;
return(broken_M_pen= ((dest>left_lim ||
  (dest>left_lim-2&&left_lim>5||dest==left_lim&&left_lim>4)&&incr>dy/2)
			&& fc<3 && maxd>3) );
}
/* descr_ce : дикриминатор 'Ц','ц' с очень короткими хвостами */
static int16_t descr_ce(uchar *r,int16_t D_X,int16_t hy)
{
uchar *rr=r+D_X;
int16_t i;
int16_t b1=LOCAL[0]-(LOCAL_W[0]>>1);
int16_t e2=LOCAL[1]+(LOCAL_W[1]>>1);
int16_t i1=SumIntervalBits(r+2*D_X,b1,(int16_t)(e2+1))/3;
int16_t num;
				/* заливка 1-ой снизу линии             */
int16_t i2=SumIntervalBits(r+D_X,b1,(int16_t)(e2+1))/3;
                                /* заливка 2-ой снизу линии             */
int16_t diap = e2-b1;               /* конец 2-ой ноги - начало 1-ой ноги   */

diap -= (diap>>3);		/* 7/8 					*/

if( i2>diap || i1>diap )        /* заливка начата во 2-ой или 3-ей линии*/
	return(1);
if( broken_flag )
	return(0);
for(num=i=0;i<hy;i++,rr-=D_X)
	{
	num+=(NumHorizInterval(rr,D_X)==2);
	if( SumIntervalBits(rr,b1,(int16_t)(e2+1))/3>=diap )
		{
		if( i>2 && num>=i-1 )
			return (1);/* по 2 интервала во всех строках i>=3 */
		else
			return(0);/* есть залитая линия                   */
		}
	}
return(1);                      /* в нижней зоне нет залитых линий      */
}


/*  DiskrJu : дискриминатор Ю (в среднем 3 интервала в каждом сечении) */
#ifdef INTERSEPTOR
static int16_t DiskrJu1(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy)
{
uchar *RASTER=RASTR;
int16_t i,ret,r,s2,s3,n,ddx;
uchar inter[256],sum[256];
ddx = bytlen(dx);

for(n=s2=s3=i=0;i<dy; i++, RASTER+=D_X,n++ )
	{
  r =  NumHorizInterval(RASTER,ddx);
	s2 += (r==2);
	}
	/*  NumHorizInterval : число интервалов в строке */

n = dy/3;
ret = 0	;

if( s3<n ) ret += n - s3;
if( !broken_flag && s2==0 ) ret += 2;
for(RASTER=RASTR,i=0;i<dx;i++)
  {
  inter[i] = NumVertInterval(RASTER, D_X, dy, i);
  sum  [i] = VertSum(RASTER, D_X, dy, i);
  }

for(r=i=0;i<dx/4;i++)
    {
    r += (inter[i]==3);
    if( r>4 )
      return 5;
    }

if( ret && (s3>0||s2>0) )
  {
  for(r=1000,n=0,i=dx/4;i<(dx*3)/4;i++)
    if( r>sum[i] && inter[i]==1 )
      {
      r=sum[i];
      n=i;
      }


  for(r=0,i=n;i<dx;i++)
    {
    r += (inter[i]==2);
    }
  if( r>4 )
    ret=0;
  }
return  (ret) ;
}
#else
/*
static int16_t DiskrJu(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly)
{
uchar *RASTER=RASTR;
int16_t i,ret,r,s2,s3,n;
dx = bytlen(dx);

for(n=s2=s3=i=0;i<Ly; i++, RASTER+=D_X,n++ )
	{
	r =  NumHorizInterval(RASTER,dx);
	s2 += (r==2);
	s3 += (r==3);
	}
  // NumHorizInterval : число интервалов в строке

n = Ly/3;
ret = 0	;
if( s3<n ) ret += n - s3;
if( !broken_flag && s2==0 ) ret += 2;
#ifdef UFA
if( ret && s3>3 )	ret = 1;
#endif
return  (ret) ;
}
*/
#endif

/* for letters 'ж' */
static int16_t DiskrJ0(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly,int16_t lim)
{
uchar *RASTER=RASTR;
int16_t i,three,n,all,ret,one;
dx = bytlen(dx);
for(one=all=three=i=0;i<Ly; i++, RASTER+=D_X )
	{
	n = NumHorizInterval(RASTER,dx);
	/*  NumHorizInterval : число интервалов в строке */
	three += ( n==3 );
	all   += ( n>=3 );
	one   += ( n==1 );
	}

if( Ly>9 )
        {
	ret = (three<lim)?lim-three:0 ;
	if( all==Ly && lim>3 )	/* в середине */
                ret = 2;
        }
else
	{ /* маленькие ж */
	if( three>=lim )
		ret = 0;
	else
		ret = (all<lim)?lim-all:0 ;
	}
if( lim<=3 && ret && one+all>Ly-3 )
	ret=0;
return( ret );
}

static int16_t Diskr3(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly)
{
uchar *RASTER=RASTR;
int16_t i,n,all,ret,one;
dx = bytlen(dx);
for(one=all=i=0;i<Ly; i++, RASTER+=D_X )
	{
	n = NumHorizInterval(RASTER,dx);
	/*  NumHorizInterval : число интервалов в строке */
	all   += ( n>=3 );
	one   += ( n==1 );
	}

ret = (all>3) ;
return( ret );
}



static int DiskrJ(unsigned char *RASTR,int D_X,int dx,int dy)
{
int i,t,tu,td,Ly=dy>>2,ly=dy-2*Ly,p,l=dy>>1;
dx = bytlen(dx);
for(tu=i=0;i<Ly; i++, RASTR+=D_X )
	tu += ( NumHorizInterval(RASTR,(uchar)dx)==3 );
for(td=t=0;i<ly; i++, RASTR+=D_X )
        {
        p = NumHorizInterval(RASTR,(uchar)dx);
	t += (p==1);
	if( i<l )
		tu += (p==3);
        if( i>l )
                td += (p==3);
        }
for(;i<dy; i++, RASTR+=D_X )
	td += ( NumHorizInterval(RASTR,(uchar)dx)==3 );
		/*  NumHorizInterval : число интервалов в строке */
return	(
	tu>3 && t>=2 && td>3 ||
	tu>1 && t>2 && td>1 && tu+td>3
	);
}

/* for letters 'ш' */
static int16_t DiskrSh(uchar *RASTR,int16_t D_X,int16_t dx,int16_t Ly)
{
uchar *RASTER=RASTR;
int16_t i,num,n2,p,ddx;
ddx = bytlen(dx);
for(n2=num=i=0;i<Ly; i++, RASTER+=D_X )
	{
	p=NumHorizInterval(RASTER,ddx);
	/*  NumHorizInterval : число интервалов в строке */
	num += ( p!=3 );
	n2 += (p==2 );
	}

if( n2 )
{	/* есть двухинтервальные строки */
int16_t b=(LOCAL[0]+LOCAL[1])/2,dd=(LOCAL[1]-LOCAL[0])+(LOCAL_W[1]+LOCAL_W[0])/2;
i = Ly<<1;
i = Ly/3-(Ly>>2);
Ly -= i;
for(RASTER=RASTR+D_X*i;i<Ly;i++, RASTER+=D_X)
	{
	p =  SumIntervalBits(RASTER,b,dx)/3;
	if( p>=dd && NumHorizInterval(RASTER,ddx)==2 )
		return 4;
	}
}
return( num>2?num-2:0 );
}

/* for letters 'ш' */
static int16_t DiskrSh0(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy,int16_t dx0)
{
uchar *RASTER=RASTR+D_X*(dy-(dy>>2));
int16_t i,num,l=dx0-(dx0>>2);
if( lower_long_line<0 )
{
dx = bytlen(dx);
for(num=0,i=dy-(dy>>2);i<dy; i++, RASTER+=D_X )
	num += ( NumHorizInterval(RASTER,dx)==1 && SumBits(RASTER, dx)>l );
		/*  num : число строк с одним длинным интервалом */
lower_long_line=num;   /* число залитых строк */
}
return( lower_long_line );
}

/*  DiskrLeft : есть ли дыра справа ? */
int16_t DiskrLeft(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy, int16_t L)
{
int16_t sum,p,x,i,Ly,p_old,curr_sum,h;
int16_t minr,maxr;
uchar *RASTER=RASTR+D_X*(dy>>2),*R;
if( left_dist[L]>=0 )
	return( left_dist[L] );
Ly=dy-2*(dy>>2);
h=Ly;
R=RASTER;

MinMaxLeft(RASTER,D_X,(uchar)dx,(uchar)Ly,&minr,&maxr);
if( minr && maxr )
	{
	minr--; maxr--;
	}
x = maxr - minr;
if( minr>(dx>>1) )
	{
  left_max = maxr-minr;
	left_line=0;
	return( (left_dist[L]=1) );
	}
left_dist[L]=(x>=L);
if( left_dist[L] )              /* big hole */
	{
        left_line=0;
	if( dy>17 )
	while( VertSum(R,D_X,h,minr)<(dy>>2) && minr<maxr)minr++;
	for(p_old=-1,curr_sum=sum=0,i=minr ; i<=maxr ; i++ )
		{
		p = NumVertInterval(R, D_X, h, i);
		if( p>=2 )
			{          /* начало серии 2-интервальных столбцов */
			if( p_old!=2 )
				curr_sum=1;
			else curr_sum++;  /* накопление ширины дырки */
			if( curr_sum>L )break;
                        }
		else if( p_old>=2 )
			{      /* конец серии 2-интервальных столбцов */
			if(  curr_sum>sum )
				sum=curr_sum;
			if( sum>=L )break;
			}
		p_old=p;
		}
	if( sum==0 && curr_sum )
		sum = curr_sum;
	left_dist[L]=( sum>=L); /* hole */
	}
else
	left_line=1;
left_max = maxr-minr;
return( left_dist[L] );
}

/*  DiskrLeftBig : есть ли бльшая дыра слева ? */
int16_t DiskrLeftBig(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy, int16_t L)
{
int16_t sum,p,x,i,Ly,p_old,curr_sum,h;
int16_t minr,maxr;
uchar *RASTER=RASTR+D_X,*R;
if( left_dist_big[L]>=0 )
	return( left_dist_big[L] );

Ly=dy-2;
h =  dy ;
R =  RASTR;

MinMaxLeft(RASTER,D_X,(uchar)dx,(uchar)Ly,&minr,&maxr);
if( minr && maxr )
	{
	minr--; maxr--;
	}
x = maxr - minr;
left_dist_big[L]=(x>=L);
if( left_dist_big[L] )              /* big hole */
	{
	if( dy>17 )
	while( VertSum(R,D_X,h,minr)<(dy>>2) && minr<maxr)minr++;
	for(p_old=-1,curr_sum=sum=0,i=minr ; i<=maxr ; i++ )
		{
		p = NumVertInterval(R, D_X, h, i);
		if( p>=2 )
			{          /* начало серии 2-интервальных столбцов */
			if( p_old!=2 )
				curr_sum=1;
			else curr_sum++;  /* накопление ширины дырки */
			if( curr_sum>L )break;
			}
		else if( p_old>=2 )
			{      /* конец серии 2-интервальных столбцов */
			if(  curr_sum>sum )
				sum=curr_sum;
			if( sum>=L )break;
			}
		p_old=p;
		}
	if( sum==0 && curr_sum )
		sum = curr_sum;
	left_dist_big[L]=( sum>=L); /* hole */
	}

return( left_dist_big[L] );
}

/*  DiskrRight : есть ли дыра справа ? */
int16_t DiskrRight(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy,int16_t L)
{
int16_t sum,p,x,dl,Ly,i,p_old,curr_sum,h;
int16_t minr,maxr,ddy;
uchar *RASTER=RASTR+D_X*(dy>>2),*R;
if( right_dist[L]>=0 )
	return( right_dist[L] );

Ly=dy-2*(dy>>2);
h=Ly;
R=RASTER;

dl=(((dx+7)>>3)<<3);
ddy = dy>30 ? (dy>>3):(dy>>2);
MinMaxRight(RASTER,D_X,(uchar)dx,(uchar)Ly,&minr,&maxr);
x = maxr - minr;
if( maxr-((dx&7)?(8-(dx&7)):0)>(dx>>1) )
	{
  right_max = maxr-minr;
  right_line=0;
	return( (right_dist[L]=1) );
	}
right_dist[L] = ( x>=L );
if( right_dist[L] )       /* big hole */
	{
	right_line=0;
	if( dy>17 )
	while( VertSum(R,D_X,h,(uchar)(dl-minr))<ddy && minr<maxr)minr++;
	for(p_old=-1,sum=curr_sum=0,i=minr ; i<=maxr ; i++ )
		{
		p = NumVertInterval(R, D_X, h, (uchar)(dl-i));
		if( p>=2 )
			{          /* начало серии 2-интервальных столбцов */
			if( p_old<2 )
				curr_sum=1;
			else curr_sum++;  /* накопление ширины дырки */
			if( curr_sum>L )break;
                        }
		else if( p_old>=2 )
			{      /* конец серии 2-интервальных столбцов */
			if(  curr_sum>sum )
				sum=curr_sum;
			if( sum>=L )break;
			}
		p_old=p;
		}
  if( sum==0 && curr_sum )
		sum = curr_sum;
	right_dist[L]=( sum>=L); /* hole */
	}
else
	right_line=1;

right_max = maxr-minr;
return( right_dist[L] );
}

/*  DiskrRightBig : есть ли большая дыра справа ? */
int16_t DiskrRightBig(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy,int16_t L)
{
int16_t sum,p,x,dl,Ly,i,p_old,curr_sum,h;
int16_t minr,maxr;
uchar *RASTER=RASTR+D_X,*R;
if( right_dist_big[L]<0 )
{
Ly=dy-2;
h =  dy ;
R =  RASTR;

dl=(((dx+7)>>3)<<3);
MinMaxRight(RASTER,D_X,(uchar)dx,(uchar)Ly,&minr,&maxr);
x = maxr - minr;
right_dist_big[L] = ( x>=L );
if( right_dist_big[L] )       /* big hole */
  {
  if( dy<13 || VertSum(RASTR, D_X, dy, (uchar)(dl-minr))<dy-2)
	{
	if( dy>17 )
	while( VertSum(R,D_X,h,(uchar)(dl-minr))<(dy>>2) && minr<maxr)minr++;
	for(p_old=-1,sum=curr_sum=0,i=minr ; i<=maxr ; i++ )
		{
		p = NumVertInterval(R, D_X, h, (uchar)(dl-i));
		if( p>=2 )
			{          /* начало серии 2-интервальных столбцов */
			if( p_old<2 )
				curr_sum=1;
			else curr_sum++;  /* накопление ширины дырки */
                        if( curr_sum>L )
                          {
                          sum = curr_sum;
                          break;
                          }
                        }
		else if( p_old>=2 )
			{      /* конец серии 2-интервальных столбцов */
			if(  curr_sum>sum )
				sum=curr_sum;
			if( sum>=L )break;
			}
		p_old=p;
		}
        if( sum==0 && curr_sum )
		sum = curr_sum;
	right_dist_big[L]=( sum>=L); /* hole */
	}
	else   right_dist_big[L]=0;  /* no hole - vert line */
  }

} /* calc right_dist */
return( right_dist_big[L] );
}


/* for letters 'C','c','e' */
static int16_t DiskrVertCE(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy,int16_t X,
                        uchar let, uchar inc)
{
uchar *RASTER=RASTR;
int16_t i,p,n,s3,d=dx>>2,wid=bytlen(dx);
int16_t ody=dy>>2;
	uchar *r=RASTR+ody*D_X;
	int16_t t1,t2,t3,num1,num2,num3,minnum,n2;
	int16_t l = dy -(ody<<1),num,z=dx-(dx>>3);
	int16_t nn[7];

if( c_or_e<0 )
	{
	d_c=0;
	/* горизонтальные исследования 	*/
	for(minnum=dx,n2=num=num1=num2=num3=0,i=ody;i<l; i++, r+=D_X )
		{
		t1=NumHorizInterval(r,wid);
		t2=SumBits(r, wid);
		if( t1==2 )
			{

			t3 = (wid<<3) - LeftDistance(r,wid)  -
					RightDistance(r,wid) - t2;
			if( n2>0 )
				{
				if( dx>10 && t3<3 )
					num3++;
				if( minnum>t3 )
					minnum=t3;
				}
			n2++;
			}
		num  += (t1==1 && t2>=z);
		num1 += (t1==1 && t2>=z-1);
		num2 += (t2>=z);
		}
		/*  num : число строк с одним длинным интервалом */
	if( num>1 || num1>2 || num2>3 || num3>1 )
		{		/* есть непрерывная перекладина */
		c_or_e = 1;     /* или набор залитых строк       */
		d_e = 0;
		d_c = num;
		if( num3 ) d_c += (minnum==1?4:3);
		return( (let==(uchar)'е')?d_e:d_c );
		}
if( num==0 && num1==0  && num2==0 && dy<24 )
{       /* ищу прыщ напротив конца правого рога */
r=RASTR+ody*D_X;
t2 = dx>>1;
for(i=ody;i<l; i++, r+=D_X )
		{
		num1=SumIntervalBits(r,t2,dx);

		if( i>ody && num!=0 && num1==0 )
			break;
		num = num1;
		}
i -= 4;
r = RASTR+i*D_X;
for(t3=t2=0;t2<7;t2++,i++,r+=D_X)
	{
	nn[t2]=EndBlackInterval(r,wid);
	t3+=(NumHorizInterval(r,wid)==2);
	}
for(t1=t2=nn[0],num=0,num1=1;num1<7;num1++)
	{
	if( t1>nn[num1] && nn[num1]>=0 )
		t1=nn[num1];
	if( t2<nn[num1] )
		t2=nn[(num=num1)];
	if( t2==nn[num1] && num==0 )
		num=num1;
	}
for(num1=num-1;num1>=0;num1--)
	if( nn[num1]<t2 )
		break;
for(num2=num+1;num2<7;num2++)
	if( nn[num2]<t2 )
		break;
if( inc && t2-t1<3 )
  t2=t1;  // Oleg : ERECTION conditions : 09-08-95 09:47pm
if( t3>2 && t2>t1 && num1>=0 && num2<7 )
	{	/* вот прыщик */
	c_or_e = 1;     /* или набор залитых строк       */
	d_e = 0;
	d_c = 1+t2-t1;
	if( (let==(uchar)'е') )
	return( d_e );
	}
}
	/* далее вертикальные исследования	*/

	dx-=d;
	X &= 7;
	for(n=s3=0,i=d;i<dx; i++)
		{
		p = NumVertInterval(RASTER, D_X, dy, (uchar)(i+X));
		s3 += ( p==3 );
		if( p==3 || p==2 )n++;
		}
		/*  NumVertInterval : число линий в столбце */
	p =  n;
	n *= 4;
	n /= 10;  /* 40 % */
	p -= n;   /* 60 % */

	c_or_e = 1;
	d_e = (s3<p)?p-s3:0;
	if( s3==0 && d_e<3 )
		d_e = 4;
	d_c = MAX(d_c,(s3>n)?s3-n+1:0);
	}
return( (let==(uchar)'е')?d_e:d_c );
}


static int16_t average_tl_angle(uchar *RASTER, int16_t D_X, int16_t dx, int16_t dy,
				int16_t t)
{
if( av_tl<0 )
	av_tl=average_angle(RASTER,D_X,dx,(int16_t)(dy>>2),LeftDistance,t);
return(av_tl);
}

static int16_t average_bl_angle(uchar *RASTER, int16_t D_X, int16_t dx, int16_t dy,
				int16_t t)
{
if( av_bl<0 )
	av_bl=average_angle(RASTER+D_X*(dy-(dy>>2)),
		D_X,dx,(int16_t)(dy>>2),LeftDistance,t);
return(av_bl);
}

static int16_t average_br_angle(uchar *RASTER, int16_t D_X, int16_t dx, int16_t dy,
				int16_t t)
{
if( av_br<0 )
	av_br=average_angle(RASTER+D_X*(dy-(dy>>2)),
		D_X,dx,(int16_t)(dy>>2),RightDistance,t);
return(av_br);
}

static int16_t average_angle(uchar *RASTER, int16_t D_X, int16_t dx, int16_t dy,
			 int16_t  (*Distance)(uchar *, int16_t), int16_t t)
{
int16_t i=0,n,p,H;
if( t==0 )
{       /* при t=0 срезаем массивные строки - ищем корни */
while( SumBits(RASTER,(uchar)bytlen(dx))>(dx>>1) && i<dy )
	{
	i++;
	RASTER+=D_X;  /* black strings */
	}
}
for(H=n=0;i<dy; i++,RASTER+=D_X)
	if( (p=Distance(RASTER,(uchar)bytlen(dx)))>=0 )
		{
		H++;
#ifdef UFA
		if( n==0 && i==dy-1 )
			continue;
#endif
		n+=p; /* nonzero string */
		}
return(H?n/H:-1);
}

static int16_t NoSymmLastColumn(uchar *raster,int16_t D_X,int16_t Dx,int16_t dy)
{
int16_t up,down,col=Dx-1,h=dy>>1;
up   = VertSum(raster,D_X,h,col);
down = VertSum(raster+D_X*h,D_X,(int16_t)(dy-h),col); /* последний столбик */
if( up+down==1 )
        {
        col--;
        up   = VertSum(raster,D_X,h,col);
        down = VertSum(raster+D_X*h,D_X,(int16_t)(dy-h),col); /* последний столбик */
        }
if( dy<15 )
	{	/* кегль 6 */
        return( (down>2 && down>up+2) || (down>1 && up==0 ) );
	}
if( up+down<=3 )
	{
	col --;
        up   = VertSum(raster,D_X,h,col);
	down = VertSum(raster+D_X*h,D_X,(int16_t)(dy-h),col);
	}                                   /* предпоследний столбик */
return( down>3 && down>up+2 );  /* внизу больше чем наверху */
}

int16_t fill_center_zone(uchar *raster,int16_t D_X,int16_t dy,
      int16_t beg, int16_t end, int16_t II)
{
int16_t i,num,l,ny,d=((end-beg)>>1),p, white, w;
uchar *r=raster;

#ifdef INTERSEPTOR
end--;beg++;
d=((end-beg)>>1);
#endif

if( fill_center>=0 )
	return( fill_center );

p = (end-beg>3 );
if( rotate )    p=0; // OLEG : ERECTION CONDITION
white=end+p-beg+1;

for(ny=num=i=0;i<dy;i++,r+=D_X)
	{
	l = SumIntervalBits(r,beg,(int16_t)(end+p))/3;
	if( i==0 && l>=d )
		continue;
  w = end+p-beg-l;
	if( white>w )
    white=w;
  if( l )
		{
		num += l;
    if( l>d )
			num+=l;
    ny++;
		}
	}

if( ny  )
	{
  if( !(rotate && (dnri_hook||II) ) )
		{
		if( end - beg < 5 )
			fill_center = ( num>ny ) ;
		else
			fill_center = ( num>(ny<<1) );
		}
	else
		{
		fill_center = 0;
    if( rotate )
      {
      if( white<2 && dnri_hook )
        fill_center = 1;
      else if( d>2 && white<d )
        fill_center = 1;
      }
		}
	}
else
	fill_center = 0;
return( fill_center );
}

/* корректность слития крыши и нижних серифов для 'П','п' */
int16_t up_down_zones(uchar *raster, int16_t D_X, int16_t dx, int16_t dx0,
			int16_t start1, int16_t stop1,
			int16_t start2, int16_t stop2)
{
int16_t i,num1,num2,l=dx0-(dx0>>3);
uchar *r=raster;
if( up_down_serif>=0 )
	return( up_down_serif );

l = MIN(l,dx0-2);
dx = bytlen(dx);
for(r=raster+start1*D_X,num1=0,i=start1;i<stop1;i++,r+=D_X)
	{
	num1 += ( NumHorizInterval(r,dx)==1 && SumBits(r, dx)>=l );
		/*  num1 : число строк с одним длинным интервалом на крыше */
	}

for(r=raster+start2*D_X,num2=0,i=start2;i<stop2;i++,r+=D_X)
	{
	num2 += ( NumHorizInterval(r,dx)==1 && SumBits(r, dx)>=l );
		/*  num2 : число строк с одним длинным интервалом внизу */
	}

if( num1==0 && num2>=1   ) /* нижние серифы слиплись, а крыша разорвана */
	return( (up_down_serif=2) );
if( num1==0 && num2==0   ) /* две палки */
	return( (up_down_serif=1) );

return( (up_down_serif=0) );
}

/* корректность слития крыши и нижних серифов для 'В','в' */
int16_t up_down_zones_for_B(uchar *raster, int16_t D_X, int16_t dx, int16_t dx0,
			int16_t start1, int16_t stop1,
			int16_t start2, int16_t stop2)
{
int16_t i,num1,num2,p,l=dx0-(dx0>>1);
uchar *r=raster;
if( up_down_serif_B>=0 )
	return( up_down_serif_B );

dx = bytlen(dx);
l = MIN( l, dx0-2);
for(r=raster+start1*D_X,num1=0,i=start1;i<stop1;i++,r+=D_X)
	{
	p = NumHorizInterval(r,dx);
	if( p==1 && SumBits(r,dx)>=l )
		break;
	num1 += ( p==2 && i>0 );
		/*  num1 : число строк с двумя интерваламм на крыше */
	}

for(r=raster+(stop2-1)*D_X,num2=0,i=stop2-1;i>=start2;i--,r-=D_X)
	{
	p = NumHorizInterval(r,dx) ;
	if( p==1 && SumBits(r,dx)>=l )
		break;
	num2 += ( p==2 && i<stop2-1);
		/*  num2 : число строк с двумя интервалами внизу */
	}

up_down_serif_B = (num1>2)+(num2>2);
return( up_down_serif_B );
}

/***************************************************************************/
/*                                                                         */
/*   возвращает   1   если   слитие   'i'  с   'д'                         */
/*   возвращает   0   иначе                                                */
/*                                                                         */
/***************************************************************************/
static int16_t DiskrTsh(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy,int16_t Dx)
/***************************************************************************/
/****     *RASTR     указатель   на  масив  с  учетом  пропуска     ********/
/****			      первой  строчки                       ********/
/****      dx        количество  битов  в  строке                   ********/
/****	   dy        kоличество  строк                              ********/
/****      D_X       количество  байтов  в  строке                  ********/
/****      Dx        количество  битов  в  строке  с  учетом        ********/
/****			      пропуска   первых  битов              ********/
/***************************************************************************/
{  uchar  j,n4=dy>>2,bool_foot=1;
   uchar  bit0,bit1,bit2;
   int16_t            i,fine=0;
   uchar  *RAST;

/****************   проверка   наличия   двух  хвостиков  ******************/


   for (RAST=RASTR+(dy-3)*D_X,i=dy-3;;i--,RAST-=D_X){
      j=SumIntervalBits( RAST,(int16_t)0,(int16_t)dx )/3 ;
      if(  (j > 5*D_X) || (i<2*n4) ) break;
      j=(uchar)NumHorizInterval( RAST, D_X );
      if( j > 1 )  fine+=20;
   }
   if( fine < 30 ){     return ( 0 );   }

/****************          положение      ног             ******************/

   bit0 = LOCAL[0] ;
   bit1 = LOCAL[1] ;
   bit2 = LOCAL[2] ;

/************   проверка   слития   в  верхнем   левом   углу  *************/

fine=0;
   for (RAST=RASTR,i=0;i<n4;i++,RAST+=D_X){
      j=SumIntervalBits(RAST,(int16_t)bit0,(int16_t)bit1)/3;
      if( j >  3*(bit1-bit0)/5 )    fine+=20;
      if( j == (bit1-bit0) )        goto end;
   }
   if( fine < 40 )   { goto   bbb;}/*razriv */

/******************  делает   гистограмму   ********************************/

   FOOT_A(RASTR, D_X, (uchar)Dx, (uchar)n4); bool_foot=0;

   for(i=bit0+1;i<bit1+1;i++){
      if(BUFFER[i]==0)  goto   bbb;/*razriv */
   }
   goto   end;/* slilos */

/************   проверка   слития   в  верхнем   правом   углу  ************/

bbb:fine=0;
   for (RAST=RASTR,i=0;i<n4;i++,RAST+=D_X){
      j=SumIntervalBits(RAST,(int16_t)bit1,(int16_t)bit2)/3;
      if( j >  3*(bit2-bit1)/5 )  	 fine+=20;
      if( j == (bit2-bit1) )             {  return(1); }
   }
   if( fine < 40 )   goto   end;/*razriv */

/******************  делает   гистограмму   ********************************/

   if( bool_foot ) FOOT_A(RASTR, D_X, (uchar)Dx, (uchar)n4);
   for(i=bit1+1;i<bit2+1;i++){
      if(BUFFER[i]==0)  goto   end;/*razriv */
   }
   return( 1 );/* slilos */

end: return ( 0 );

}  /* DiskrTsh */

int16_t small_density(uchar *RAST,int16_t n,int16_t D_X,int16_t bw)
{
int16_t i,l,w,d;
int16_t b = bw << 3;

if( !omni && font_type==0 )
	return(1);

for(l=i=0;i<n;i++,RAST+=D_X)
	{
	w = b - RightDistance(RAST,bw) - LeftDistance(RAST,bw);
	d = SumBits(RAST,bw);
	l += (d>w-2);
	}

return( l<=(n/3) );
}

int16_t no_serific(uchar *RASTR,int16_t dy,int16_t dx,int16_t wb)
{
int16_t l0=VertSum(RASTR,wb,dy,0);
int16_t l1=VertSum(RASTR,wb,dy,1);
int16_t l2=VertSum(RASTR,wb,dy,2);
int16_t r0=VertSum(RASTR,wb,dy,(int16_t)(dx-1));
int16_t r1=VertSum(RASTR,wb,dy,(int16_t)(dx-2));
int16_t r2=VertSum(RASTR,wb,dy,(int16_t)(dx-3));
dy -= 2;
if( l0<dy && l1<=dy && l1>dy-2 && l2>dy )
	l1=l2;
if( r0<dy && r1<=dy && r1>dy-2 && r2>dy )
	r1=r2;
return ( l0>dy || l1>dy ) && ( r0>dy || r1>dy ) ;
}

int16_t vert_stairs(int16_t arr[], int16_t lim)
{
int16_t i,old,jmp;
for(jmp=0,i=1,old=arr[0];i<lim;i++)
	{
	if( arr[i]==-1 )
		continue;
	if( old<arr[i] )
		jmp++;
	if( old>arr[i] )
		return 0;
	old = arr[i];
	}
return ( jmp );
}

/***************************************************************************/
/*                                                                         */
/*  возвращает   оценку возрастания середин интервалов перкладины ИН       */
/*                                                                         */
/***************************************************************************/
static void DiskrIN(uchar *RASTR,int16_t D_X,int16_t dy,int16_t bw,int16_t dx)
/***************************************************************************/
/****     *RASTR     указатель   на  массив                         ********/
/****	   dy        kоличество  строк                              ********/
/****      D_X       количество  байтов  в  строке                  ********/
/***************************************************************************/
{  uchar  n[256],hist[256];
   int16_t   ua[256],da[256];
   int16_t  i,n2=dy-2*(dy>>2),n4,mean,fine;
   int16_t 	incr,decr,old,neue,equ;
   int16_t  l=beg2-end1-1,l_real,t,jump,rmin,rmax;
   int16_t  ol=1,or=1;	/* зазор слева и справа */
   uchar *RAST ,*R;


n4 = MAX(dy/4,(LOCAL_W[0]+LOCAL_W[1])/4);
if( n4>dy/3 ) n4=dy/4;
n2 = dy - (n4<<1);
RAST = RASTR+D_X*n4;

if( IN_dis>0 )
	return;
IN_IN_Monus=0;
IN_pics=1;
IN_M=0;

if( l+ol+or<2 && dy>19 )
	{
	if( small_density(RAST,n2,D_X,bw) )
		{			/* нет заливки */
		IN_N=4;
		IN_I=2;
		}
	else
		{			/* заливка	*/
		IN_N=4;
		IN_I=3;
		}
	IN_dis=1;
	IN_equ=0;
	return;
	}

memset(hist,0,dy);
if( l<3 )
	{	/* отменить зазоры */
	or=ol=0;
	l=beg2-end1+1-ol-or;
	}
if( l>3 )
{
int16_t up_space=-1, down_space=-1;
int16_t up_fill=0,down_fill=0,d;
for(R=RAST,i=n4;i<=dy-2;i++,R+=D_X)
	{
	d=SumIntervalBits(R,(int16_t)(end1+ol),(int16_t)(beg2-or+1))/3;
	hist[i]=(uchar)d;
	if( d==l && !up_fill )
		up_fill=i;
	if( d==l && i<n4+n2 )
		down_fill=i;
	}

if( up_fill && down_fill && up_fill>n4 &&
	(hist[up_fill-1]==0||hist[up_fill-2]==0) &&
	(hist[down_fill+1]==0||hist[down_fill+2]==0) )
	{
	IN_N=3;
	IN_I= 2;
	IN_dis=1;
	IN_equ=1;
	return;
	}

for( old=hist[n4],i=n4+1;i<=n2;i++)
	{
	neue = hist[i];
	if( up_space==-1 )
	if( old==1 && neue>=l && hist[i+1]>=l ||
	    old==0 && neue>=l-1 && hist[i+1]>=l )
	    {
	    if( NumHorizInterval(RASTR+D_X*(i+1),bw)==1 )
        {
        int16_t j,d;
        up_space = (neue==l ? 0 : 1);

        for(j=i+1;j<dy-2 && hist[j]>=l-1;j++);
        if( j<dy-2 )
          {
          for(d=0;j<dy-2;j++)
            d+=(hist[j]<hist[j-1]);
          if( d>2 )
            {
            up_space=-1;
            break;
            }
          if( d<3 )
            {
            down_space=0;
            break;
            }
          }
      }
  }
	if( down_space==-1 )
	if( neue==1 && old>=l && hist[i-2]>=l ||
	    neue==0 && old>=l-1 && hist[i-2]>=l )
	    {
	    if( NumHorizInterval(RASTR+D_X*(i-2),bw)==1 )
        down_space = (old==l ? 0 : 1);
	    }
	old = neue;
	}

if( up_space!=-1 && down_space!=-1 )
	{
	IN_N=3;
	IN_I= MIN(up_space,down_space);
	IN_dis=1;
	IN_equ=2;
	return;
	}
memset(hist,0,dy<<1);
} /* end of horiz study */

if( no_serific(RASTR,dy,dx,bw) )
	{
	n4 = dy>17 ? 4 : 2;
	n2 = dy - (n4<<1);
	RAST = RASTR+D_X*n4;
	}
memset(ua,0xFF,dy<<1);
memset(da,0xFF,dy<<1);
i = end1+ol-1;
n[i] = (uchar)CenterVertInterval( RAST, D_X, n2, i,&ua[i],&da[i] );
				/* запасной левый отсчет 		*/
for(mean=l_real=0,i=end1+ol;i<=beg2-or;i++)
	{	/* таблица отчетов середин вертикальных интервалов 	*/
	n[i] = (uchar)CenterVertInterval( RAST, D_X, n2, i,&ua[i],&da[i] );
	mean += n[i];
	if( n[i] )              /* mean	  - сумма   отсчетов		*/
		l_real++;	/* l_real - число ненулевых отсчетов 	*/
	}
n[i] = (uchar)CenterVertInterval( RAST, D_X, n2, i,&ua[i],&da[i]);
				/* запасной отсчет 			*/
if( l!=l_real && (l_real==2 || (n[end1]|n[end1+1]) && (n[beg2]|n[beg2-1])) )
	{           	/* отсутствие перекладины 			*/
	IN_N_Bonus=2;
	IN_I_Bonus=2;
	if( l_real==2 )
		IN_P_Bonus=1;
	}
if( l_real<=1 && ((n[end1]==0&&n[end1+1]==0) || (n[beg2]==0&&n[beg2-1]==0)) )
	{           	/* отсутствие перекладины 			*/
	IN_N_Bonus=1;
	IN_P_Bonus=1;
	IN_I_Bonus=1;
	if( n[end1]==0 && n[end1+1]==0 && n[beg2]==0 && n[beg2-1]==0 )
		{
		IN_P_Bonus=2;
		IN_N_Bonus=1;
		IN_I_Bonus=1;
		}
	}

if( no_serific(RASTR,dy,dx,bw) )
	{	/* обратный пересчет в интервал высот [dy/4,dy-dy/4] */
	int16_t nn4,nn2,h;
	nn4 = MAX(dy>>2,(LOCAL_W[0]+LOCAL_W[1])>>1);
  if( nn4>dy/3 ) nn4=dy/4;
  nn2 = dy - (nn4<<1);
  RAST = RASTR+D_X*n4;
	for(mean=l_real=0,i=end1;i<=beg2;i++)
		{
		h = n2+n4-(n[i]>>1);
		if( h<nn4 || h>nn4+nn2 )
			n[i]=0;
		else
			{
			n[i] += ((nn2+nn4-n2-n4)<<1);
			if( n[i]>=(nn2<<1) )
				n[i]=0;
			else if( n[i] &&
				 (i!=end1||i==end1&&ol==0) &&
				 (i!=beg2||i==beg2&&or==0) )
				{
        mean += n[i];
				l_real++;
				}
			}
		}
	n2=nn2;
	n4=nn4;
	}
if( l_real<4 )
	 {
	 i = beg2-or+1;
	 if( or && n[i] && VertSum(RAST, D_X, n2, i)<n2-1 &&
		NumVertInterval(RAST, D_X, n2, i)==1 )
		{	/* учитываем последний отсчет */
		mean += n[i];
		or--;
		l_real++;
		l++;
		}
	 i = end1+ol-1;
	 if( ol && n[i] && VertSum(RAST, D_X, n2, i)<n2-1 &&
		NumVertInterval(RAST, D_X, n2, i)==1 )
		{	/* учитываем последний отсчет */
		mean += n[i];
		ol--;
		l_real++;
		l++;
		}
	 }
if( l_real<=1 )
{
int16_t dy1=n2/*dy>>1*/,nn,mm,mm1,minup,mindown,zaz;
uchar *rrrr,*rrrr1;
zaz = beg2 - end1;
for(	minup=mindown=zaz, rrrr=RASTR, rrrr1=RASTR+(dy-1)*D_X, i=0;
	i<3;	i++, rrrr+=D_X, rrrr1-=D_X)
	{
	mm = zaz-SumIntervalBits(rrrr,end1,beg2)/3;
	if( minup>mm )
		minup = mm;
	mm1 = zaz-SumIntervalBits(rrrr1,end1,beg2)/3;
	if( mindown>mm1 )
		mindown = mm1;
	nn=dx-SumBits(rrrr,bw);
	if( nn<2 )
		break;
	}
if( i<3 || (minup*2<mindown && minup*3<zaz && zaz>3) )
	{ /* почти залитая крышка */
	IN_N_Bonus=IN_I_Bonus=1;IN_P_Bonus=2;
	}
else
	{
	if( (nn=n[end1+ol])>0 )
		{
		IN_N_Bonus=IN_I_Bonus=IN_P_Bonus=1;
		if( abs(nn-dy1)<3 )
			IN_N_Bonus=2;
		else if( nn<dy1-2 )
			IN_I_Bonus=2;
		}
	else	if( (nn=n[beg2-or])>0 )
		{
		IN_N_Bonus=IN_I_Bonus=IN_P_Bonus=1;
		if( abs(nn-dy1)<3 )
			IN_N_Bonus=2;
		else if( nn>dy1+2 )
			IN_I_Bonus=2;
		}
	}
}
{
int16_t z=beg2-end1+1;
if( z>4 && l_real*2>z )
	IN_IN_Monus=1;	/* А перекладины разрыв то маленький ! */
if( 	l_real>4 	|| 	l-l_real<=3 && l>5 ||
	l_real==4 && fill_center ||
	l_real<2 && z<4 && n4<6 ||
	z>10 && l_real<3 )
	{
	IN_P_Bonus=IN_I_Bonus=IN_N_Bonus=0;
	}

}

if( l_real>1 )
	{
	for(i=end1+ol;i<=beg2-or;i++)
		if( (neue=n[i])!=0 )
			hist[ neue ]++;

	mean=mean/l_real+((mean%l_real)>(l_real>>1));
				/* mean	  - средний отсчет		*/

	if( hist[mean-1]>l_real-2 )
		mean--;
	if( hist[mean+1]>l_real-2 )
		mean++;

if( l_real!=l && !(l_real==l-1 && (n[end1]==0||n[beg2]==0) ) )
if( !fill_center && l_real<=4 || l_real<=3 )
	{
	int16_t an[2],en[2],ll,dy1=n2,san[2],sen[2],z;
	/* поиск прыщей от 'Н' на середине высоты */
	an[0]=n[end1];
	an[1]=n[end1+1];
	en[0]=n[beg2-1];
	en[1]=n[beg2];
	for(ll=i=0;i<2;i++)
		{
		sen[i]=n[beg2-i];
		san[i]=n[end1+i];
		if( an[i]>0 )
			{
			if( abs(an[i]-dy1)>2 )
				an[i]=-1;
			else
				n[end1+i]=(uchar)dy1,ll++;
			}
		if( en[i]>0 )
			{
			if( abs(en[i]-dy1)>2 )
				en[i]=-1;
			else
				n[beg2-i]=(uchar)dy1,ll++;
			}
		}
	if( IN_I_Bonus==2 && ll==1 )
		IN_I_Bonus=1;
	if( ll>2 || ll==2 && broken_flag )
		{
		for(i=0;i<2;i++)
			{
			if( an[i]>0 )
				n[end1+i]=(uchar)dy1;
			if( en[i]>0 )
				n[beg2-i]=(uchar)dy1;
			}
		mean =  dy1;
		fill_center=1;
		IN_N_Bonus=2;
		IN_P_Bonus=IN_I_Bonus=0;
		}
	else
		{
		for(i=0;i<2;i++)
			{
			n[beg2-i]=(uchar)sen[i];
			n[end1+i]=(uchar)san[i];
			}
	/* поиск прыщей от 'И' по разные стороны от середины высоты */
		an[0]=n[end1];
		an[1]=n[end1+1];
		en[0]=n[beg2-1];
		en[1]=n[beg2];
		for(ll=i=0;i<2;i++)
			{
			z=VertSum(RAST, D_X, n2, (int16_t)(end1+i));
			if( an[i]>0 && an[i]<dy1-2 && z<n4 )
				ll++;
			z=VertSum(RAST, D_X, n2, (int16_t)(beg2-i));
			if( en[i]>0 && en[i]>dy1+2 && z<n4)
				ll++;
			}
#ifndef INTERSEPTOR
    if( ll>2 || ll==2 && broken_flag && !rotate)
#else
    if( ll>3 || ll==2 && broken_flag && !rotate)
#endif
			{
			fill_center=1;
			IN_I_Bonus=2;
			IN_P_Bonus=IN_N_Bonus=0;
			}
		}
	}
else
{
if( fill_center && l_real>l-3 && l>2 )
{
int16_t lim = (beg2-or-end1+ol)>>1;
for(t=0,i=end1+ol;i<=lim;i++)
	if( n[i]>((n2-2)<<1) )
		t++;
	if( t>=MAX(2,(l_real>>1)) )
	{		/* перекладина слишком высоко 			*/
	fill_center=0;	/* коррекция штрафа за отстутствие перекладины 	*/
	IN_N=4;
	IN_I=1;
	IN_dis=1;
	return;
	}
}

if( fill_center && l_real<2 && l>4 )
	{               /* полное отсутствие перекладины 		*/
	fill_center=0;	/* коррекция штрафа за отстутствие перекладины 	*/
	IN_N=4;
	IN_I=1;
	IN_dis=1;
	return;
	}
}


for(old=incr=decr=fine=0,i=end1+ol,rmin=dy,rmax=0;i<=beg2-or;i++)
	if( (neue=n[i])!=0 )
		{	/* fine - сумма расстояний от среднего 	*/
		if( old==0 )
			old = neue;/* первый ненулевой отсчет	*/
		if( neue>rmax )
			rmax=neue;
		if( neue<rmin )
			rmin=neue;
		if( neue>mean )
			fine += neue - mean;
		else
			fine += mean-neue;
		if( neue>old )
			incr++;   /* число скачков возрастаний 	*/
		else if( neue<old )
			decr++;   /* число скачков убываний 	*/
		old = neue;
		}
if( fine && rmax-rmin<=2 && !(l_real==3 && incr==2) )
	fine=0;	/* все отсчеты в 2-х линиях */
if( fine && l_real==3 && incr==2 )
	fine+=2;	/* 2 скачка в 3-х столбцах */

if( omni ){
int16_t fin=fine,inc=incr,dec=decr;

neue = n[end1];
if( ol && neue && neue<n[end1+1] )
	{
	if( neue>mean )
		fin += neue - mean;
	else
		fin += mean-neue;
	inc++;   /* число скачков возрастаний 	*/
	}

neue = n[beg2];
if( or && neue && neue>n[beg2-1])
	{
	if( neue>mean )
		fin += neue - mean;
	else
		fin += mean-neue;
	inc++;   /* число скачков возрастаний 	*/
	}
/* большое сходство с 'И' */
if( fin>10 && inc>3 && dec<1  && LOCAL[0] <= dx/4)
	IN_M=80;
else if( fin>10 && inc>2 && dec==0 && LOCAL[0] <= dx/4)
	IN_M=80;
else
	IN_M=0;
	}
if( 	abs(incr-decr)<2 && 	/* близкие значения скачков 	*/
	(incr>1 &&              /* более 1 возрастания		*/
	decr>1 ||		/* более 1 убывания		*/
	incr && decr && incr+decr<4 ) &&	/* мало скачков */
	fine<=l			/* малая дисперсия		*/
  )
		fine=0;
if( incr<2   &&            /* маловато возрастаний   */
    l_real>4 &&            /* на широкой перекладине */
    decr && incr+decr<4 )  /* скачков немного        */
 fine=0;
	if( fine>2 && incr<2 && decr>1 && l>3 )
		fine -= 2;		/* всего 1 возрастание		*/
	t = (incr<=1)&&(decr<=1);
	for(i=end1+ol; n[i]==0 && i<=beg2-or;i++); /* skip empty columns */
	for(equ=incr=0,old=n[i++];i<=beg2-or;i++)
		{
		if( n[i] )
			neue=n[i];
		else
			continue;
		if( neue>old )
			incr += neue-old;
		old = neue;
		}
	if( t==0 )              /* более 1-го возрастания или убывания 	*/
		fine += incr ;	/* добавили штраф за возрастание	*/
	for(t=equ=i=0;i<dy;i++)
		if( hist[i]>equ )
			equ=hist[(t=i)];
	if( 	fine>1 && equ>2 && t==mean && or==0 && ol==0 &&
		n[end1]<mean && mean<n[beg2] && equ+2==l_real )
			fine=0;	/* 1-ый и последний скачки в	*/
				/* разорванном растре, интервал	*/
				/* постоянства длины 3		*/
	if( equ>1 && fine<6 )
		{
		int16_t fineold=fine;
		t = n4 + n2 - (t>>1);
		for( RAST=RASTR+D_X*(t-2),i=t-2;i<=t+2;i++,RAST+=D_X)
			if( SumIntervalBits(RAST,end1,(int16_t)(beg2+1))==
				(beg2-end1+1)*3 )
				{		/* есть перекладина */
				fine=0;
				break;
				}
		if( equ==2 && (ol&&n[end1+ol] || or&&n[beg2-or]) )
			fine=fineold;
		}

	if( l_real<5 && equ>2 )
		fine=0;		/* 3 из 4(или <4) совпадают 		*/
	if( l_real>4 && equ>l_real-2 )
		fine = 0;	/* совпадают l-1 из l отсчетов		*/
	jump=0;
	if( equ==l-1 )
		{		/* единственный всплеск			*/
		i=end1+ol;
		if( n[i]!=0 && n[i]<n[i+1] && n[i+2]==n[i+1] )
			{
			fine=0;	/* единственный левый всплеск		*/
			jump=1;
			}
		else
			{
			i=beg2-or;
			if( n[i-1]!=0 && n[i]>n[i-1] && n[i-2]==n[i-1] )
				{
				fine=0;
				/* единственный правый всплеск		*/
				jump=1;
				}
			}
		}
if( l_real>2 )
	{		/* нормировка накопленного штрафа 	*/
	fine <<= 5;     /* *32 ?????????????			*/
	fine /= l_real; /* истинная ширина 			*/
	fine /= n2;     /* высота				*/
	}

	}
else
	{
	fine=0; 	/* l_real<2 : не можем оценить образ 	*/
	IN_dis=1;
	IN_equ=IN_N=0;
	IN_I=3;
	IN_pics=0;
	if( fill_center && l>2 )
		fill_center=0;	/* коррекция штрафа за отстутствие перекладины */
	if( 	!fill_center && l_real==1 &&
		(NumVertInterval(RAST, D_X, n2, end1)==1 &&
		 VertSum(RAST,D_X,n2,end1)<n4 &&
		 n[end1] && abs(n[end1]-(dy>>1))<3 ||
		 NumVertInterval(RAST, D_X, n2, beg2)==1 &&
		 VertSum(RAST,D_X,n2,beg2)<n4 &&
		 n[beg2] && abs(n[beg2]-(dy>>1))<3) )
		fill_center=2;

	return;
	}

IN_N=IN_I = fine;	/*           штраф за возрастание 	*/
if( incr<2 && l_real>5 && decr>4 )
	{
	if( fine>6 )
		IN_N=5;
	IN_I=1;   /* similar to N */
  }
if( incr<1 && l_real>3 && decr>l_real/2 )
	{
  IN_N=6;
	IN_I=1;   /* similar to N */
  }
if( fine==0 && jump )
	IN_I=3;
if( !fill_center && (l_real>3 || l_real>l-3) && l>2 && mean*4<dy*3 )
	{
	if( l_real>2 || n[end1] && n[beg2] )
#ifdef INTERSEPTOR
  if( l_real>5 )
#endif
  if( !rotate || l_real>3 )
  fill_center=1;  /* коррекция штрафа за отстутствие перекладины */
	}
if( fine>5 && l_real==2 && !broken_flag && incr==0 && decr==1 )
	{
	IN_N=4;
	IN_I=2;
	fill_center=0;
	}
IN_dis=1;
equ -= l-2;
IN_equ = (equ>0)?2+equ:0;	/* IN_equ -штраф за постоянство */

if( DiskrHorizIN(RASTR,D_X,dy) )
			{   /* жирная перекладина */
			IN_N=3;
			IN_I=2;
			}
if( omni )
	{	/* 'И' путается с 'М' */
	int16_t i,le,ri,nnn=(beg2+end1+ol-or)/2;
	if( fine>15 && decr>3 || fine>20 && decr>2 ||
	    fine>10 && incr<1 && decr>3 )
		IN_I=1;
	if( l_real>4 && fine>9 )
	{
	for(old=n[end1+ol],le=0,i=end1+ol;i<nnn;i++)
		{
		neue = n[i];
		if( neue )
			{
			if( neue<old )
				le++;
			old=neue;
			}
		}
	for(old=n[i],ri=0;i<beg2-or;i++)
		{
		neue = n[i];
		if( neue )
			{
			if( neue>old )
				ri++;
			old=neue;
			}
		}
	if( le>3 && ri>3 )
		IN_I=1;
	}
	}

{
int16_t up_skip=vert_stairs(&ua[end1],(int16_t)(beg2-end1+1));
int16_t down_skip=vert_stairs(&da[end1],(int16_t)(beg2-end1+1));

if( IN_I<=3 )
if( up_skip>3 && down_skip>3 ||
    up_skip>1 && down_skip>1 && up_skip+down_skip>4 )
	{
	IN_N=4;
	IN_I= 4;
	IN_dis=1;
	IN_equ=0;
	return;
	}
}

return;
} 			/* 		DiskrIN 		*/

/***************************************************************************/
int16_t DiskrHorizIN(uchar *RASTR,int16_t D_X,int16_t dy)
/***************************************************************************/
/****     *RASTR     указатель   на  массив                         ********/
/****	   dy        kоличество  строк                              ********/
/****      D_X       количество  байтов  в  строке                  ********/
/***************************************************************************/
{  uchar n[256];
   int16_t  i,j,n2=dy-2*(dy>>2),n4=dy>>2,imax,nmax,kmax;
   int16_t l = beg2 - end1 ,h;
   uchar *RAST = RASTR+D_X*n4;


if( IN_horiz_dis>=0 )
	return(IN_horiz_dis);

if( l<4 )
	{ /* малое расстояние */
	IN_horiz_dis=0;
	return(IN_horiz_dis);
	}

for(imax=nmax=kmax=-1,i=n4,j=0;j<=n2;j++,i++,RAST+=D_X)
	{	/* заливки линий 	*/
	n[i] = SumIntervalBits(RAST,end1,beg2)/3;
	if( n[i]>nmax )
		{
		nmax = n[i];
		imax = i;
		kmax=1;
		}
	else if( n[i]==nmax )
		kmax++;
	}

if( imax>0 && nmax==l && kmax>1 )
	{
	for(i=imax;n[i]==nmax;i--);
	h = ( n[i-1]==0 && n[i]<3 || n[i]<2 ) ;
	for(i=imax;n[i]==nmax;i++);
	l = ( n[i+1]==0 && n[i]<3 || n[i]<2 ) ;
	}
else
	l=h=0;

return (IN_horiz_dis= (h&&l) ) ;
} 			/* 		DiskrHorizIN 		*/

static int16_t DiskrEZ(uchar *RASTR,int16_t D_X,int16_t dx,int16_t dy)
/***************************************************************************/
/****     *RASTR     указатель   на  масив  с  учетом  пропуска     ********/
/****			      первой  строчки                       ********/
/****      dx        количество  битов  в  строке                   ********/
/****	   dy        kоличество  строк                              ********/
/****      D_X       количество  байтов  в  строке                  ********/

/*  return   1  for   З    */
/*      2  for   Э    */

/***************************************************************************/
{  uchar  j;
   int16_t n4=dy>>2,n2=dy>>1;
   uchar  j1,j2,j3,j4;
   int16_t            i;
   uchar  *RAST,*r1,*r2;

if( diskr_EZ>=0 )
	return ( diskr_EZ);
diskr_EZ=0;
   dx-=2;
   for (RAST=RASTR+n4*D_X,i=0;i<n2;i++,RAST+=D_X)
     {
        j=(uchar)SumIntervalBits( RAST,2,dx ) ;
        if( j>9 ) {  r1=RAST; break; }
      }
   if( i==n2 )           return(0);        /* не  определ  перекл */

   for (RAST=RASTR+(dy-n4)*D_X,i=0;i<n2;i++,RAST-=D_X)
     {
      j=(uchar)SumIntervalBits( RAST,2,dx ) ;
      if( j>9 )   {  r2=RAST; break; }
     }
   if( i==n2 )           return(0);        /* не  определ  перекл */

   j1=(uchar)SumIntervalBits( r1-  D_X,2,dx );
   j2=(uchar)SumIntervalBits( r1-2*D_X,2,dx );
   j3=(uchar)SumIntervalBits( r2+  D_X,4,dx );
   j4=(uchar)SumIntervalBits( r2+2*D_X,4,dx );

   j1 = (j1-j2>=3 );
   j3 = (j3-j4>=3 );



   if( j1 && j3 )
	diskr_EZ=2; /* 2 ступеньки */

   if( (!j1) && (!j3) )
	diskr_EZ=1;  /* нет ступенек */

   return(diskr_EZ);        /* неопределенность */
}  /* DiskrEZ */

static int16_t horiz_density(uchar *RAST,int16_t D_X,int16_t dx,int16_t beg,int16_t end)
/***************************************************************************/
/****     *RAST      указатель   на  масив  с  учетом  пропуска     ********/
/****			      первой  строчки                       ********/
/****      dx        количество  битов  в  строке                   ********/
/****	   dy        kоличество  строк                              ********/
/****      D_X       количество  байтов  в  строке                  ********/
/***************************************************************************/
{  uchar  j,*r;
   int16_t i,n_count=0,n=end-beg,den_x;
   dx-=1;
   den_x=3*(dx-(dx>>3));
   for (r=RAST+beg*D_X,i=0;i<=n;i++,r+=D_X){
      j=(uchar)SumIntervalBits( r,1,dx ) ;
      if( j>=den_x )
	{  n_count++; }
   }

   return(n_count);        /* ... */
}  /*  */

static int16_t DiskrimM(uchar *RAST,int16_t D_X,int16_t dx,int16_t dy)
/***************************************************************************/
/****     *RAST      указатель   на  масив                          ********/
/****      dx        количество  битов  в  строке                   ********/
/****	   dy        kоличество  строк                              ********/
/****      D_X       количество  байтов  в  строке                  ********/
/***************************************************************************/
{
   int16_t    n2,n4=dy>>2,meanBit=dx>>1; /* Oleg & Vova 09.03.94 */
   int16_t    i,j,k,up=0,down=0,cUp=0,cDown=0;
   int16_t    prev=0,byte=0;
   uchar   *r;

/*  calculate  mean  of  hole  */
   for(r=RAST+D_X,i=0;i<n4;i++,r+=D_X){
      j = NumHorizInterval( r, D_X );
      if( j == 2 ){
	 for(k=0;k<dx;k++){
	    byte=k>>3;
	    byte=*(r+byte);
	    byte >>= ( 7- (k % 8) );
	    byte &= 0x1;
	    if( !byte && prev  && !down )  down = k;
	    if(  byte && !prev && down )   up   = k;
	    prev = byte;
	 }
   meanBit = ( up+down+(dx>>1) )/3;
	 /* for  no  wide  letters */
	 if( (up-down < 5) || (dx<dy) )  meanBit = ( up+down )/2;
	 break;
      }
   }
if( down==0 && up==0 )  return(2); /* м - hole is absent */

/*  calculate  heigth  of  hole  */
   r=RAST+D_X;
   byte = 0;
   prev = whiteMeanBitLeft(r,D_X,meanBit) +
	  whiteMeanBitRight(r,D_X,dx,meanBit);
   for(i=1;i<dy-1;i++,r+=D_X){
      j = whiteMeanBitLeft(r,D_X,meanBit) +
	  whiteMeanBitRight(r,D_X,dx,meanBit);
      if( (j == 0) && (i > n4+1) ){  break;  }
      byte += (prev-j);
      /* for  'ы' */
      if( (byte < 2) && (i > n4+2) ){
         break;
      }
      prev = j;
   }
   if( i > dy-2 )  i = 2*dy/3;
   n4 = i>>1;  n2 = 2*n4;
/*  calculate  symetry  of  hole  */
   down = up = byte = 0;
   r=RAST+D_X;
   prev = whiteMeanBitLeft(r,D_X,meanBit) +
          whiteMeanBitRight(r,D_X,dx,meanBit);
   for(i=1;i<=n2;i++,r+=D_X){
      j = whiteMeanBitLeft(r,D_X,meanBit) +
	  whiteMeanBitRight(r,D_X,dx,meanBit);
      if( i<=n4 ){  up   += j;  cUp++;    }
      else       {  down += j;  cDown++;  }
      /* too  wide  hole */
      if( (i>n4) && (j>dx/3) ){
	 if( (cUp==0) || (cDown==0) )  return(0);
	 if( up*cDown <= down*cUp )    return(4);  /* ы - too  wide  hole */
	 if( byte < 3 )                return(3);  /* ы - too  wide  hole */
      }
      byte += (prev-j);
      if( (prev-j > 3) && (i>n4) )  return(5);      /* ы - too  big  jump */
      if( (byte >= dx/4) && (i>n4) )  return( -6 ); /* м - too  big  angle  for  cursive */
      prev = j;
   }

   if( (cUp != cDown) && (cDown) ){  down *= cUp;  down /= cDown;  }
   if( down >= up )  return(5);  /* ы - wide  hole on  the  bottom */
   if( down < up )  return(-5); /* м - wide  hole on  the  top */
   if( !cDown )  return(6);  /* ы - hole is absent */

   return(0);
}  /* DiskrM */

static int16_t DiskrimM1(uchar *RAST,int16_t D_X,int16_t dx,int16_t dy)
/***************************************************************************/
/****     *RAST      указатель   на  масив                          ********/
/****      dx        количество  битов  в  строке                   ********/
/****	   dy        kоличество  строк                              ********/
/****      D_X       количество  байтов  в  строке                  ********/
/***************************************************************************/
{
   int16_t    n2,n4=dy>>2,meanBit=dx>>1; /* Oleg & Vova 09.03.94 */
   int16_t    i,j,k,up=0,down=0,cUp=0,cDown=0;
   int16_t    prev=0,byte=0;
   uchar   *r;

/*  calculate  mean  of  hole  */
   for(r=RAST+D_X,i=0;i<n4;i++,r+=D_X){
      j = NumHorizInterval( r, D_X );
      if( j == 2 ){
	 if( ( j = NumHorizInterval( r+D_X, D_X ) ) ==2 ){
	    r += D_X;
	 }
	 for(k=0;k<dx;k++){
	    byte=k>>3;
	    byte=*(r+byte);
	    byte >>= ( 7- (k % 8) );
	    byte &= 0x1;
	    if( !byte && prev  && !down )  down = k;
	    if(  byte && !prev && down )   up   = k;
	    prev = byte;
	 }
	 meanBit = ( up+down+(dx>>1) )/3;
	 /* for  no  wide  letters */
	 if( (up-down < 5) || (dx<dy) )  meanBit = ( up+down )/2;
	 break;
      }
   }

/*  calculate  heigth  of  hole  */
   r=RAST+D_X;
   byte = 0;
   prev = whiteMeanBitLeft(r,D_X,meanBit);
   for(i=1;i<dy-1;i++,r+=D_X){
      j = whiteMeanBitLeft(r,D_X,meanBit);
      if( (j == 0) && (i > n4+1) ){  break;  }
      byte += (prev-j);
      /* for  'ы' */
      if( (byte < 1) && (i > n4+2) ){
	 break;
      }
      prev = j;
   }
   if( i > dy-2 )  i = 2*dy/3;
   n4 = i>>1;  n2 = 2*n4;

/*  calculate  symetry  of  hole  */
   down = up = byte = 0;
   r=RAST+D_X;
   prev = whiteMeanBitLeft(r,D_X,meanBit);
   for(i=1;i<=n2;i++,r+=D_X){
      j = whiteMeanBitLeft(r,D_X,meanBit);
      if( i<=n4 ){  up   += j;  cUp++;    }
      else       {  down += j;  cDown++;  }
      /* too  wide  hole */
      if( (i>n4) && (j>dx/5) ){
	 if( (cUp==0) || (cDown==0) )  return(0);
	 if( up*cDown <= down*cUp )    return(4);  /* ы - too  wide  hole */
	 if( byte < 1 )                return(3);  /* ы - too  wide  hole */
      }
      byte += (prev-j);
      if( (prev-j > 3) && (i>n4) )  return(5);      /* ы - too  big  jump */
      if( (byte > 1+dx/8) && (i>n4) )  return( -6 ); /* м - too  big  angle  for  cursive */
      prev = j;
   }

   if( (cUp != cDown) && (cDown) ){  down *= cUp;  down /= cDown;  }
   if( down >= up )  return(5);  /* ы - wide  hole on  the  bottom */
   if( down < up )  return(-5); /* м - wide  hole on  the  top */
   if( !cDown )  return(6);  /* ы - hole is absent */

   return(0);
}  /* DiskrM1 */

static int16_t whiteMeanBitLeft(uchar *RAST,int16_t D_X,int16_t meanBit)
/***************************************************************************/
/****     *RAST      указатель   на  масив  с  учетом  пропуска     ********/
/****			      первой  строчки                       ********/
/****      dx        количество  битов  в  строке                   ********/
/****      D_X       количество  байтов  в  строке                  ********/
/***************************************************************************/
{
   int16_t    meanByte, byte;
   int16_t    i,counter=0;

   for(i=meanBit;i>=0;i--){
      meanByte = i>>3;
      byte = *(RAST+meanByte);
      byte >>= ( 7- (i % 8) );
      byte &= 0x1;
      if(byte){
         meanByte = (i-1)>>3;
	 byte = *(RAST+meanByte);
	 byte >>= ( 7- ((i-1) % 8) );
	 byte &= 0x1;
	 if(byte)  break;
	 else{
	    meanByte = i>>3;
	    byte = *(RAST+D_X+meanByte);
	    byte >>= ( 7- (i % 8) );
	    byte &= 0x1;
            if(byte)  break;
	    else{
	       meanByte = i>>3;
	       byte = *(RAST-D_X+meanByte);
	       byte >>= ( 7- (i % 8) );
	       byte &= 0x1;
	       if(byte)  break;
	       else      counter++;
	    }
         }
      }
      else  counter++;
   }

   return( counter );
}  /* whiteMeanBitLeft */

static int16_t whiteMeanBitRight(uchar *RAST,int16_t D_X,int16_t dx,int16_t meanBit)
/***************************************************************************/
/****     *RAST      указатель   на  масив  с  учетом  пропуска     ********/
/****			      первой  строчки                       ********/
/****      dx        количество  битов  в  строке                   ********/
/****      D_X       количество  байтов  в  строке                  ********/
/***************************************************************************/
{
   int16_t    meanByte, byte;
   int16_t    i,counter=0;

   for(i=meanBit+1;i<dx;i++){
      meanByte = i>>3;
      byte = *(RAST+meanByte);
      byte >>= ( 7- (i % 8) );
      byte &= 0x1;
      if(byte){
	 meanByte = (i+1)>>3;
	 byte = *(RAST+meanByte);
	 byte >>= ( 7- ((i+1) % 8) );
	 byte &= 0x1;
	 if(byte)  break;
	 else{
	    meanByte = i>>3;
	    byte = *(RAST+D_X+meanByte);
	    byte >>= ( 7- (i % 8) );
	    byte &= 0x1;
            if(byte)  break;
	    else{
	       meanByte = i>>3;
	       byte = *(RAST-D_X+meanByte);
	       byte >>= ( 7- (i % 8) );
	       byte &= 0x1;
	       if(byte)  break;
	       else      counter++;
	    }
         }
      }
      else  counter++;
   }

   return( counter );
}  /* whiteMeanBitRight */

int16_t LepikJurit( uchar *R, int16_t D_X, int16_t dy)
{
  int16_t y2,y4,i;
  int16_t ug,ugg, bg;
  int16_t us/*,bs*/;   /* Oleg : Lepic ne jurit etoi peremennoi */
  int16_t uu;
  int16_t ret;
  uchar *r;
  y2 = dy/2;
  y4 = dy/4;
  ug = bg = 0;
  for (i = 0, r = R+D_X*y4; i <y4;  i++ ,r+=D_X )
      {
        ret = LeftEdgeOfRightmostInt (r, D_X);
        if (ug <ret){  ug = ret; us =i;}
      }
 ugg = ug;
  for (         ;    i <y2;   i++, r+= D_X)
      {
        ret = LeftEdgeOfRightmostInt (r, D_X);
	if (bg <ret) { bg = ret; /* bs =i;*/}
      }
 uu = 0;
 for (i =us+1, r =R +D_X*(y4+i); i <y4+2; i++, r+=D_X)
  {
        ret = LeftEdgeOfRightmostInt (r, D_X);
        if ((ret <ug) &&(ug -ret<3)) { uu++; ug =ret;}
	 else if((uu >= 2)) break;
                else uu=0;
  }


 return ((ugg < bg)||(uu>=2)) ? 1 : 0;
}

/* 1 строка пропущена сверху, 1 - снизу */
int16_t up_down_hist_M(uchar *rastr,int16_t D_X, int16_t Dx,int16_t dy)
{
int16_t i,j,d,h=dy>>1,s,t,n;
uchar *r;

Dx =  bytlen(Dx);
for(s=j=0,i=0,r=rastr+i*D_X;i<h;j++,i++,r+=D_X)
	{
	n = NumHorizInterval( r, Dx ) ;
	s += (n==2);
	if( s>2 )               break;
	if( j>3 && s==0 )       break;
	}
if( s<2 )			return(0);

for(t=d=j=0,i=dy-1,r=rastr+i*D_X; i>=h;i--,j++,r-=D_X)
	{
	n = NumHorizInterval( r, Dx ) ;
	t += (n==3);
	d += (n==2);
	if( d>2 )		break;
	if( t>2 )   		break;
	if( j>3 && t==0 )	break;
	}

if( t<2 )			return(0);

if( s>3 && t>3 )		return( 8 );
return(4);
}

/*  для 'ш': ноги на одинаковом расстоянии? Да: <0; нет: >0; неясно: 0 */
static int16_t DiskrSymSh( uchar *RASTER, int16_t Wx, uchar NWIDTH, uchar NLENGTH)
{
  int16_t i,old,l,k,d;
  uchar c,w,minw=255,maxw=0;

  FOOT_A(RASTER,Wx,NWIDTH,NLENGTH);       /* проекция */

d=(NLENGTH+1)>>1;
for(i=0;i<NWIDTH;i++)
	BUFFER[i] = (BUFFER[i]>=d); /* бинаризация */

for(old=l=k=i=0;i<=NWIDTH;i++)
	{
    c = (i<NWIDTH) ? BUFFER[i] : 0;
	if( old^c )
		{
        if( c )
			l=i;			/* черная  : начало ноги */
		else
            {               /* белая   : конец ноги  */
            w=i-l;
            if (w>maxw)  maxw=w;
            if (w<minw)  minw=w;
            LOCAL_W[k]=w;    /* ширина ноги   */
            LOCAL[k]=(l+i);  /* центр+1/2 с точностью до 1/2 пиксела */
            k++;
			}
		}
	old=c;
	}

  if ( k != 3 || maxw-minw>1 )  return(0);    //странная буква
  i=LOCAL[2]+LOCAL[0]-(LOCAL[1]<<1);          //асимметрия
  if (i==0)  return (-2);
  if (i<0) i=-i;
  if( i<3 && NWIDTH>22 )  i=1;  //Oleg:02-13-96: too small for wide image
  i=(i<<6)/(32+NWIDTH);
  if (i==1) i=0;
  return(i);
}
