home *** CD-ROM | disk | FTP | other *** search
- /* verctorop.c vectorization routine for stscan.c */
- #include <exec/exec.h>
- #include <exec/types.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <graphics/rastport.h>
- #include <libraries/reqbase.h>
- #include <req_pragmas.h>
- #include <stdio.h>
- #include <string.h>
- #include <functions.h>
- #include "stscan.h"
-
- #define REGION_SIZE 64
- #define CHAINLEN 16384
-
- static UWORD chpixels[2][CHAINLEN];
- static UWORD lnpixels[2][CHAINLEN];
- static UWORD regio_x[128][128];
- static UWORD regio_y[128][128];
- static UBYTE regio_done[128][128];
- static UBYTE regio_numx,regio_numy;
- static char str_filenam[REQ_FCHARS+REQ_DSIZE]="";
- static UWORD maxdiff=4;
-
- static UBYTE getpixel(UWORD x,UWORD y)
- {
- return((*(memptr+(ULONG)y*(ULONG)membpl+(ULONG)(x>>3))&bitval[x&7])?0:1);
- }
-
- 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()
- { UWORD x,y;
- UBYTE f,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()
- { UWORD x,y,i;
- ULONG pgofs1,pgofs2;
- UBYTE p,f,ende;
- char wtitel[80];
-
- 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,"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()
- { UWORD p,x,y,len;
- FILE *vecfile;
- char wtitel[80];
-
- if (filerequest("Save Vector 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,"Chain %04d",++p);
- SetWindowTitles(win,&wtitel[0],(UBYTE *)-1);
- }
- }
- }
- fclose(vecfile);
- SetWindowTitles(win," ",(UBYTE *)-1);
- }
- }
-
- void chngmaxdiff()
- { struct Process *OurTask;
- struct Window *old_pr_WindowPtr;
- struct GetLongStruct gnum;
-
- OurTask = (struct Process *)FindTask((char *)0L);
- old_pr_WindowPtr = OurTask->pr_WindowPtr;
- OurTask->pr_WindowPtr = win;
- memset(&gnum,0,sizeof(gnum));
- gnum.titlebar = "Enter vectorization accuracy.";
- gnum.defaultval = maxdiff;
- gnum.minlimit = 2;
- gnum.maxlimit = 100;
- if (GetLong(&gnum)) maxdiff=gnum.result;
- OurTask->pr_WindowPtr = old_pr_WindowPtr;
- }
-