home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 625.lha / STScan_v2.0 / vectorop.c < prev   
C/C++ Source or Header  |  1992-02-22  |  9KB  |  337 lines

  1. /* verctorop.c vectorization routine for stscan.c */
  2. #include <exec/exec.h>
  3. #include <exec/types.h>
  4. #include <intuition/intuition.h>
  5. #include <intuition/intuitionbase.h>
  6. #include <libraries/dos.h>
  7. #include <libraries/dosextens.h>
  8. #include <graphics/rastport.h>
  9. #include <libraries/reqbase.h>
  10. #include <req_pragmas.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <functions.h>
  14. #include "stscan.h"
  15.  
  16. #define REGION_SIZE 64
  17. #define CHAINLEN 16384
  18.  
  19. static UWORD chpixels[2][CHAINLEN];
  20. static UWORD lnpixels[2][CHAINLEN];
  21. static UWORD regio_x[128][128];
  22. static UWORD regio_y[128][128];
  23. static UBYTE regio_done[128][128];
  24. static UBYTE regio_numx,regio_numy;
  25. static char str_filenam[REQ_FCHARS+REQ_DSIZE]="";
  26. static UWORD maxdiff=4;
  27.  
  28. static UBYTE getpixel(UWORD x,UWORD y)
  29.   return((*(memptr+(ULONG)y*(ULONG)membpl+(ULONG)(x>>3))&bitval[x&7])?0:1);
  30. }
  31.  
  32. static void clrpixel(UWORD x,UWORD y)
  33. { *(memptr+(ULONG)y*(ULONG)membpl+(ULONG)(x>>3))|=bitval[x&7];
  34. }
  35.  
  36. static void setpixel(UWORD x,UWORD y)
  37. { *(memptr+(ULONG)y*(ULONG)membpl+(ULONG)(x>>3))&=invbitval[x&7];
  38. }
  39.  
  40. static UBYTE subiter(UWORD nx,UWORD ny)
  41. { UWORD x,y;
  42.   UBYTE f,vw,vnw,vn,vne,ve,vse,vs,vsw;
  43.  
  44.   f=0;
  45.   for (y=regio_y[nx][ny];y<regio_y[nx][ny+1];y++)
  46.   { for (x=regio_x[nx][ny];x<regio_x[nx+1][ny];x++)
  47.     { if ((getpixel(x,y))&&((x&1)==(y&1)))
  48.       { vw= getpixel(x-1,y);
  49.         vnw=getpixel(x-1,y-1);
  50.         vn= getpixel(x  ,y-1);
  51.         vne=getpixel(x+1,y-1);
  52.         ve= getpixel(x+1,y);
  53.         vse=getpixel(x+1,y+1);
  54.         vs= getpixel(x  ,y+1);
  55.         vsw=getpixel(x-1,y+1);
  56.         if ( (( ((vw^1)&(vnw|vn))
  57.                +((vn^1)&(vne|ve))
  58.                +((ve^1)&(vse|vs))
  59.                +((vs^1)&(vsw|vw)) )==1)
  60.             || ((!(vw))&&(!(vnw))&&(!(vn))&&(!(vne))&&
  61.                 (!(ve))&&(!(vse))&&(!(vs))&&(!(vsw)) ) )
  62.         { clrpixel(x,y);
  63.           if (!(f)) f=((vnw|vse)&(vne|vsw)&(vn|vs)&(vw|ve));
  64.         }
  65.       }
  66.     }
  67.   }
  68.   for (y=regio_y[nx][ny];y<regio_y[nx][ny+1];y++)
  69.   { for (x=regio_x[nx][ny];x<regio_x[nx+1][ny];x++)
  70.     { if ((getpixel(x,y))&&((x&1)!=(y&1)))
  71.       { vw= getpixel(x-1,y);
  72.         vnw=getpixel(x-1,y-1);
  73.         vn= getpixel(x  ,y-1);
  74.         vne=getpixel(x+1,y-1);
  75.         ve= getpixel(x+1,y);
  76.         vse=getpixel(x+1,y+1);
  77.         vs= getpixel(x  ,y+1);
  78.         vsw=getpixel(x-1,y+1);
  79.         if ( (( ((vw^1)&(vnw|vn))
  80.                +((vn^1)&(vne|ve))
  81.                +((ve^1)&(vse|vs))
  82.                +((vs^1)&(vsw|vw)) )==1)
  83.             || ((!(vw))&&(!(vnw))&&(!(vn))&&(!(vne))&&
  84.                 (!(ve))&&(!(vse))&&(!(vs))&&(!(vsw)) ) )
  85.         { clrpixel(x,y);
  86.           if (!(f)) f=((vnw|vse)&(vne|vsw)&(vn|vs)&(vw|ve));
  87.         }
  88.       }
  89.     }
  90.   }
  91.   return(f);
  92. }
  93.  
  94. static UBYTE chkblack(UWORD nx,UWORD ny)
  95. { UWORD x,y;
  96.   UBYTE f=1;
  97.   for (y=regio_y[nx][ny];y<regio_y[nx][ny+1];y++)
  98.   { for (x=regio_x[nx][ny];x<regio_x[nx+1][ny];x++)
  99.     if (!(getpixel(x,y))) 
  100.     { f=0;
  101.       y=regio_y[nx][ny+1];
  102.       x=regio_x[nx+1][ny];
  103.     }
  104.   }
  105.   return(f);
  106. }
  107.  
  108. static void straighten()
  109. { UWORD x,y;
  110.   UBYTE f,vnw,vne,vse,vsw;
  111.  
  112.   for (y=1;y<memheight-1;y++)
  113.   { for (x=1;x<memwidth-1;x++)
  114.     { if ((getpixel(x,y))
  115.           &&(!(getpixel(x-1,y)))&&(!(getpixel(x+1,y)))
  116.           &&(!(getpixel(x,y-1)))&&(!(getpixel(x,y+1))))
  117.       { vnw=getpixel(x-1,y-1);
  118.         vne=getpixel(x+1,y-1);
  119.         vse=getpixel(x+1,y+1);
  120.         vsw=getpixel(x-1,y+1);
  121.         if (((vnw))&&(!(vne))&&(!(vse))&&((vsw))) 
  122.         { clrpixel(x,y);
  123.           setpixel(x-1,y);
  124.         }
  125.         else if ((!(vnw))&&((vne))&&((vse))&&(!(vsw))) 
  126.         { clrpixel(x,y);
  127.           setpixel(x+1,y);
  128.         }
  129.         else if (((vnw))&&((vne))&&(!(vse))&&(!(vsw))) 
  130.         { clrpixel(x,y);
  131.           setpixel(x,y-1);
  132.         }
  133.         else if ((!(vnw))&&(!(vne))&&((vse))&&((vsw))) 
  134.         { clrpixel(x,y);
  135.           setpixel(x,y+1);
  136.         }
  137.       }
  138.     }
  139.   }
  140. }
  141.  
  142. void thin()
  143. { UWORD x,y,i;
  144.   ULONG pgofs1,pgofs2;
  145.   UBYTE p,f,ende;
  146.   char wtitel[80];
  147.   
  148.   membpl=(memwidth>>3);
  149.   pgofs1=(memwidth>>3)*(memheight-1);
  150.   for (i=0;i<(memwidth>>3);i++) 
  151.   { *(memptr+i)=255;
  152.     *(memptr+pgofs1+i)=255;
  153.   }
  154.   pgofs1=0;
  155.   pgofs2=membpl-1;
  156.   for (i=0;i<memheight;i++)
  157.   { *(memptr+pgofs1)|=128;
  158.     *(memptr+pgofs2)|=1;
  159.     pgofs1+=membpl;
  160.     pgofs2+=membpl;
  161.   }
  162.   p=1;
  163.   regio_numx=memwidth/REGION_SIZE;
  164.   regio_numy=memheight/REGION_SIZE;
  165.   regio_x[0][0]=1;
  166.   regio_x[1][0]=REGION_SIZE+(memwidth%REGION_SIZE)/2;
  167.   for (x=2;x<regio_numx;x++) regio_x[x][0]=REGION_SIZE+regio_x[x-1][0];
  168.   regio_x[regio_numx][0]=memwidth-1;
  169.   for (x=0;x<regio_numx;x++) regio_y[x][0]=1;
  170.   for (x=0;x<=regio_numx;x++)
  171.   { regio_y[x][1]=REGION_SIZE+(memheight%REGION_SIZE)/2;
  172.     regio_x[x][1]=regio_x[x][0];
  173.   }
  174.   for (y=2;y<regio_numy;y++) for (x=0;x<=regio_numx;x++)
  175.   { regio_y[x][y]=REGION_SIZE+regio_y[x][y-1];
  176.     regio_x[x][y]=regio_x[x][0];
  177.   }
  178.   for (x=0;x<regio_numx;x++) regio_y[x][regio_numy]=memheight-1;
  179.   for (y=0;y<regio_numy;y++) for (x=0;x<regio_numx;x++) regio_done[x][y]=1;
  180.   do
  181.   { ende=0;
  182.     for (y=0;y<regio_numy;y++) for (x=0;x<regio_numx;x++)
  183.     { if (regio_done[x][y])
  184.       { if (subiter(x,y)) f=regio_done[x][y]=1;
  185.         else if (chkblack(x,y)) f=regio_done[x][y]=1;
  186.         else f=regio_done[x][y]=0;
  187.         ende|=f;
  188.         sprintf(&wtitel,"Region (%02d;%02d) Pass %02d",x,y,p);
  189.         SetWindowTitles(win,&wtitel[0],(UBYTE *)-1);
  190.       }
  191.     }
  192.     p++;
  193.   } while (ende);
  194.   SetWindowTitles(win,"Cleanup",(UBYTE *)-1);
  195.   straighten(); 
  196.   SetWindowTitles(win," ",(UBYTE *)-1);
  197. }
  198.  
  199. static UWORD getchain(UWORD x, UWORD y)
  200. { UWORD lx,ly,pos;
  201.   UBYTE f=1;
  202.  
  203.   lx=x;
  204.   ly=y;
  205.   pos=0;
  206.   while ((f)&&(pos<CHAINLEN))
  207.   { chpixels[0][pos]=lx;
  208.     chpixels[1][pos]=ly;
  209.     clrpixel(lx,ly);
  210.     pos++;
  211.          if (getpixel(lx-1,ly  )) lx--;
  212.     else if (getpixel(lx-1,ly-1)) {lx--; ly--;}
  213.     else if (getpixel(lx  ,ly-1)) ly--;
  214.     else if (getpixel(lx+1,ly-1)) {lx++; ly--;}
  215.     else if (getpixel(lx+1,ly  )) lx++;
  216.     else if (getpixel(lx+1,ly+1)) {lx++; ly++;}
  217.     else if (getpixel(lx  ,ly+1)) ly++;
  218.     else if (getpixel(lx-1,ly+1)) {lx--; ly++;}
  219.     else f=0;
  220.   }
  221.   return(pos);
  222. }
  223.  
  224. static UWORD getline(UWORD x0, UWORD y0, UWORD x1, UWORD y1)
  225. { WORD xdiff,ydiff,xstep,ystep, sum;
  226.   UWORD i;
  227.   WORD step[2]={-1,1};
  228.  
  229.   xstep=step[(x0<x1)]; ystep=step[(y0<y1)];
  230.   xdiff=abs(x0-x1); ydiff=abs(y0-y1);
  231.  
  232.   lnpixels[0][0]=x0;
  233.   lnpixels[1][0]=y0;
  234.   i=1;
  235.   if (xdiff>ydiff)
  236.   { sum=xdiff/2;
  237.     while (x0!=x1)
  238.     { x0+=xstep;
  239.       sum-=ydiff;
  240.       if (sum<0)
  241.       { y0+=ystep;
  242.         sum+=xdiff;
  243.       }
  244.       lnpixels[0][i]=x0;
  245.       lnpixels[1][i]=y0;
  246.       i++;
  247.     }
  248.   }
  249.   else
  250.   { sum=ydiff/2;
  251.     while (y0!=y1)
  252.     { y0+=ystep;
  253.       sum-=xdiff;
  254.       if (sum<0)
  255.       { x0+=xstep;
  256.         sum+=ydiff;
  257.       }
  258.       lnpixels[0][i]=x0;
  259.       lnpixels[1][i]=y0;
  260.       i++;
  261.     }
  262.   }
  263.   return(i);
  264. }
  265.  
  266. static void polygon(UWORD startpos,UWORD len,FILE *vecfile)
  267. { UWORD sx0,sy0,sx1,sy1,m,n,s,lnlen,cbdist,mcbdist,mdpos;
  268.   
  269.   sx0=chpixels[0][startpos];
  270.   sy0=chpixels[1][startpos];
  271.   sx1=chpixels[0][startpos+len-1];
  272.   sy1=chpixels[1][startpos+len-1];
  273.   lnlen=getline(sx0,sy0,sx1,sy1);
  274.   mdpos=0;
  275.   mcbdist=0;
  276.   s=len/lnlen;
  277.   if (s<1) s=1;
  278.   for(m=0,n=startpos;m<lnlen;m++,n+=s)
  279.   { cbdist=abs(chpixels[0][n]-lnpixels[0][m])
  280.           +abs(chpixels[1][n]-lnpixels[1][m]);
  281.     if (cbdist>mcbdist)
  282.     { mdpos=m;
  283.       mcbdist=cbdist;
  284.     }
  285.   }
  286.   if (mcbdist>maxdiff)
  287.   { polygon(startpos,mdpos,vecfile);
  288.     polygon(startpos+mdpos,len-mdpos,vecfile);
  289.   }
  290.   else
  291.   { fprintf(vecfile,"%d %d\n",sx0,memheight-sy0);
  292.     fprintf(vecfile,"%d %d\n\n",sx1,memheight-sy1);
  293.   }
  294. }
  295.  
  296. void vectorize()
  297. { UWORD p,x,y,len;
  298.   FILE *vecfile;
  299.   char wtitel[80];
  300.   
  301.   if (filerequest("Save Vector TXT File",str_filenam))
  302.   { p=0;
  303.     membpl=(memwidth>>3);
  304.     vecfile=fopen(str_filenam,"w");
  305.     for (y=1;y<memheight-1;y++)
  306.     { for (x=1;x<memwidth-1;x++)
  307.       { if (getpixel(x,y))
  308.         { len=getchain(x,y);
  309.           polygon(0,len,vecfile);
  310.           sprintf(&wtitel,"Chain %04d",++p);
  311.           SetWindowTitles(win,&wtitel[0],(UBYTE *)-1);
  312.         }
  313.       }
  314.     }
  315.     fclose(vecfile);
  316.     SetWindowTitles(win," ",(UBYTE *)-1);
  317.   }
  318. }
  319.  
  320. void chngmaxdiff()
  321. { struct Process *OurTask;
  322.   struct Window    *old_pr_WindowPtr;
  323.   struct GetLongStruct    gnum;
  324.  
  325.   OurTask = (struct Process *)FindTask((char *)0L);
  326.   old_pr_WindowPtr = OurTask->pr_WindowPtr;
  327.   OurTask->pr_WindowPtr = win;
  328.   memset(&gnum,0,sizeof(gnum));
  329.   gnum.titlebar = "Enter vectorization accuracy.";
  330.   gnum.defaultval = maxdiff;
  331.   gnum.minlimit = 2;
  332.   gnum.maxlimit = 100;
  333.   if (GetLong(&gnum)) maxdiff=gnum.result;
  334.   OurTask->pr_WindowPtr = old_pr_WindowPtr;
  335. }
  336.