home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 44
/
Amiga_Dream_44.iso
/
Amiga
/
workbench
/
pilotes
/
scanners
/
StScan.lha
/
StScan
/
vectorop.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-08-11
|
8KB
|
334 lines
/*
** $VER: vectorop.c 3.00D (11.8.97)
**
** STScan vectorization routines
**
** Written by Frank-Christian Kruegel, Henning Peters, Andreas R. Kleinert
** GNU General Public License V2
*/
#include "stscan.h"
#define REGION_SIZE 64
#define CHAINLEN 16384
static UWORD __far chpixels[2][CHAINLEN];
static UWORD __far lnpixels[2][CHAINLEN];
static UWORD __far regio_x[128][128];
static UWORD __far regio_y[128][128];
static UBYTE __far regio_done[128][128];
static UBYTE __far regio_numx,regio_numy;
static char str_filenam[256]="";
static UWORD maxdiff=4;
static UBYTE getpixel(UWORD x,UWORD y)
{
UBYTE res;
res = (UBYTE) (*(memptr+(ULONG)y*(ULONG)membpl+(ULONG)(x>>3))&bitval[x&7])?0:1;
return(res);
}
static void clrpixel(UWORD x,UWORD y)
{ *(memptr+(ULONG)y*(ULONG)membpl+(ULONG)(x>>3))|=bitval[x&7];
}
static void setpixel(UWORD x,UWORD y)
{ *(memptr+(ULONG)y*(ULONG)membpl+(ULONG)(x>>3))&=invbitval[x&7];
}
static UBYTE subiter(UWORD nx,UWORD ny)
{ UWORD x,y;
UBYTE f,vw,vnw,vn,vne,ve,vse,vs,vsw;
f=0;
for (y=regio_y[nx][ny];y<regio_y[nx][ny+1];y++)
{ for (x=regio_x[nx][ny];x<regio_x[nx+1][ny];x++)
{ if ((getpixel(x,y))&&((x&1)==(y&1)))
{ vw= getpixel(x-1,y);
vnw=getpixel(x-1,y-1);
vn= getpixel(x ,y-1);
vne=getpixel(x+1,y-1);
ve= getpixel(x+1,y);
vse=getpixel(x+1,y+1);
vs= getpixel(x ,y+1);
vsw=getpixel(x-1,y+1);
if ( (( ((vw^1)&(vnw|vn))
+((vn^1)&(vne|ve))
+((ve^1)&(vse|vs))
+((vs^1)&(vsw|vw)) )==1)
|| ((!(vw))&&(!(vnw))&&(!(vn))&&(!(vne))&&
(!(ve))&&(!(vse))&&(!(vs))&&(!(vsw)) ) )
{ clrpixel(x,y);
if (!(f)) f=((vnw|vse)&(vne|vsw)&(vn|vs)&(vw|ve));
}
}
}
}
for (y=regio_y[nx][ny];y<regio_y[nx][ny+1];y++)
{ for (x=regio_x[nx][ny];x<regio_x[nx+1][ny];x++)
{ if ((getpixel(x,y))&&((x&1)!=(y&1)))
{ vw= getpixel(x-1,y);
vnw=getpixel(x-1,y-1);
vn= getpixel(x ,y-1);
vne=getpixel(x+1,y-1);
ve= getpixel(x+1,y);
vse=getpixel(x+1,y+1);
vs= getpixel(x ,y+1);
vsw=getpixel(x-1,y+1);
if ( (( ((vw^1)&(vnw|vn))
+((vn^1)&(vne|ve))
+((ve^1)&(vse|vs))
+((vs^1)&(vsw|vw)) )==1)
|| ((!(vw))&&(!(vnw))&&(!(vn))&&(!(vne))&&
(!(ve))&&(!(vse))&&(!(vs))&&(!(vsw)) ) )
{ clrpixel(x,y);
if (!(f)) f=((vnw|vse)&(vne|vsw)&(vn|vs)&(vw|ve));
}
}
}
}
return(f);
}
static UBYTE chkblack(UWORD nx,UWORD ny)
{ UWORD x,y;
UBYTE f=1;
for (y=regio_y[nx][ny];y<regio_y[nx][ny+1];y++)
{ for (x=regio_x[nx][ny];x<regio_x[nx+1][ny];x++)
if (!(getpixel(x,y)))
{ f=0;
y=regio_y[nx][ny+1];
x=regio_x[nx+1][ny];
}
}
return(f);
}
static void straighten(void)
{ UWORD x,y;
UBYTE vnw,vne,vse,vsw;
for (y=1;y<memheight-1;y++)
{ for (x=1;x<memwidth-1;x++)
{ if ((getpixel(x,y))
&&(!(getpixel(x-1,y)))&&(!(getpixel(x+1,y)))
&&(!(getpixel(x,y-1)))&&(!(getpixel(x,y+1))))
{ vnw=getpixel(x-1,y-1);
vne=getpixel(x+1,y-1);
vse=getpixel(x+1,y+1);
vsw=getpixel(x-1,y+1);
if (((vnw))&&(!(vne))&&(!(vse))&&((vsw)))
{ clrpixel(x,y);
setpixel(x-1,y);
}
else if ((!(vnw))&&((vne))&&((vse))&&(!(vsw)))
{ clrpixel(x,y);
setpixel(x+1,y);
}
else if (((vnw))&&((vne))&&(!(vse))&&(!(vsw)))
{ clrpixel(x,y);
setpixel(x,y-1);
}
else if ((!(vnw))&&(!(vne))&&((vse))&&((vsw)))
{ clrpixel(x,y);
setpixel(x,y+1);
}
}
}
}
}
void thin(void)
{ UWORD x,y,i;
ULONG pgofs1,pgofs2;
char wtitel[96];
UBYTE p,f,ende;
membpl=(memwidth>>3);
pgofs1=(memwidth>>3)*(memheight-1);
for (i=0;i<(memwidth>>3);i++)
{ *(memptr+i)=255;
*(memptr+pgofs1+i)=255;
}
pgofs1=0;
pgofs2=membpl-1;
for (i=0;i<memheight;i++)
{ *(memptr+pgofs1)|=128;
*(memptr+pgofs2)|=1;
pgofs1+=membpl;
pgofs2+=membpl;
}
p=1;
regio_numx=memwidth/REGION_SIZE;
regio_numy=memheight/REGION_SIZE;
regio_x[0][0]=1;
regio_x[1][0]=REGION_SIZE+(memwidth%REGION_SIZE)/2;
for (x=2;x<regio_numx;x++) regio_x[x][0]=REGION_SIZE+regio_x[x-1][0];
regio_x[regio_numx][0]=memwidth-1;
for (x=0;x<regio_numx;x++) regio_y[x][0]=1;
for (x=0;x<=regio_numx;x++)
{ regio_y[x][1]=REGION_SIZE+(memheight%REGION_SIZE)/2;
regio_x[x][1]=regio_x[x][0];
}
for (y=2;y<regio_numy;y++) for (x=0;x<=regio_numx;x++)
{ regio_y[x][y]=REGION_SIZE+regio_y[x][y-1];
regio_x[x][y]=regio_x[x][0];
}
for (x=0;x<regio_numx;x++) regio_y[x][regio_numy]=memheight-1;
for (y=0;y<regio_numy;y++) for (x=0;x<regio_numx;x++) regio_done[x][y]=1;
do
{ ende=0;
for (y=0;y<regio_numy;y++) for (x=0;x<regio_numx;x++)
{ if (regio_done[x][y])
{ if (subiter(x,y)) f=regio_done[x][y]=1;
else if (chkblack(x,y)) f=regio_done[x][y]=1;
else f=regio_done[x][y]=0;
ende|=f;
sprintf(&wtitel[0],"Region (%02d;%02d) Pass %02d",x,y,p);
SetWindowTitles(win,&wtitel[0],(UBYTE *)-1);
}
}
p++;
} while (ende);
SetWindowTitles(win,"Cleanup",(UBYTE *)-1);
straighten();
SetWindowTitles(win," ",(UBYTE *)-1);
}
static UWORD getchain(UWORD x, UWORD y)
{ UWORD lx,ly,pos;
UBYTE f=1;
lx=x;
ly=y;
pos=0;
while ((f)&&(pos<CHAINLEN))
{ chpixels[0][pos]=lx;
chpixels[1][pos]=ly;
clrpixel(lx,ly);
pos++;
if (getpixel(lx-1,ly )) lx--;
else if (getpixel(lx-1,ly-1)) {lx--; ly--;}
else if (getpixel(lx ,ly-1)) ly--;
else if (getpixel(lx+1,ly-1)) {lx++; ly--;}
else if (getpixel(lx+1,ly )) lx++;
else if (getpixel(lx+1,ly+1)) {lx++; ly++;}
else if (getpixel(lx ,ly+1)) ly++;
else if (getpixel(lx-1,ly+1)) {lx--; ly++;}
else f=0;
}
return(pos);
}
static UWORD getline(UWORD x0, UWORD y0, UWORD x1, UWORD y1)
{ WORD xdiff,ydiff,xstep,ystep, sum;
UWORD i;
WORD step[2]={-1,1};
xstep=step[(x0<x1)]; ystep=step[(y0<y1)];
xdiff=abs(x0-x1); ydiff=abs(y0-y1);
lnpixels[0][0]=x0;
lnpixels[1][0]=y0;
i=1;
if (xdiff>ydiff)
{ sum=xdiff/2;
while (x0!=x1)
{ x0+=xstep;
sum-=ydiff;
if (sum<0)
{ y0+=ystep;
sum+=xdiff;
}
lnpixels[0][i]=x0;
lnpixels[1][i]=y0;
i++;
}
}
else
{ sum=ydiff/2;
while (y0!=y1)
{ y0+=ystep;
sum-=xdiff;
if (sum<0)
{ x0+=xstep;
sum+=ydiff;
}
lnpixels[0][i]=x0;
lnpixels[1][i]=y0;
i++;
}
}
return(i);
}
static void polygon(UWORD startpos,UWORD len,FILE *vecfile)
{ UWORD sx0,sy0,sx1,sy1,m,n,s,lnlen,cbdist,mcbdist,mdpos;
sx0=chpixels[0][startpos];
sy0=chpixels[1][startpos];
sx1=chpixels[0][startpos+len-1];
sy1=chpixels[1][startpos+len-1];
lnlen=getline(sx0,sy0,sx1,sy1);
mdpos=0;
mcbdist=0;
s=len/lnlen;
if (s<1) s=1;
for(m=0,n=startpos;m<lnlen;m++,n+=s)
{ cbdist=abs(chpixels[0][n]-lnpixels[0][m])
+abs(chpixels[1][n]-lnpixels[1][m]);
if (cbdist>mcbdist)
{ mdpos=m;
mcbdist=cbdist;
}
}
if (mcbdist>maxdiff)
{ polygon(startpos,mdpos,vecfile);
polygon(startpos+mdpos,len-mdpos,vecfile);
}
else
{ fprintf(vecfile,"%d %d\n",sx0,memheight-sy0);
fprintf(vecfile,"%d %d\n\n",sx1,memheight-sy1);
}
}
void vectorize(void)
{ UWORD p,x,y,len;
FILE *vecfile;
char wtitel[96];
if (filerequest("Speichern Vektor TXT File",str_filenam))
{ p=0;
membpl=(memwidth>>3);
vecfile=fopen(str_filenam,"w");
for (y=1;y<memheight-1;y++)
{ for (x=1;x<memwidth-1;x++)
{ if (getpixel(x,y))
{ len=getchain(x,y);
polygon(0,len,vecfile);
sprintf(&wtitel[0],"Chain %04d",++p);
SetWindowTitles(win,&wtitel[0],(UBYTE *)-1);
}
}
}
fclose(vecfile);
SetWindowTitles(win," ",(UBYTE *)-1);
}
}
void chngmaxdiff(void)
{
ULONG longnum;
longnum = maxdiff;
if(rtGetLong(&longnum, "Enter vectorization accuracy", NULL,
RTGL_ShowDefault, TRUE,
RTGL_Min, 2,
RTGL_Max, 100,
TAG_END)) maxdiff=longnum;
}