home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 320_01 / convolve.lst < prev    next >
File List  |  1990-08-06  |  7KB  |  309 lines

  1. Listing 1 - Convolution program
  2.  
  3. /*****************************************************************/
  4. /* CONVOLVE.C - Turbo C 2.0 implementation of image convolution  */
  5. /* ----------   by Wesley G. Faler.  All code is "as is".  There */
  6. /* is NO copyright.  Use this code as you will, and if you make  */
  7. /* money at it, good for you.                                    */
  8. /*****************************************************************/
  9.  
  10. #include<stdlib.h>
  11. #include<stdio.h>
  12. #include<graphics.h>
  13. #include<alloc.h>
  14. #include<ctype.h>
  15.  
  16. int load_cut(char *fname);
  17. int load_convolution_matrix(char *fname);
  18. int convolve_image(void);
  19. int swap_pictures(void);
  20.  
  21. int minx,maxx,miny,maxy;
  22. int LOADPAGE=0;
  23. int ENHANCEPAGE=1;
  24. int *cmat, *pmat, *vmat;
  25. int cmx,cmy,cmnum;
  26.  
  27. struct palettetype palette,newpal;
  28. int driver,mode;
  29.  
  30. int cleancut=-1;
  31.  
  32. int init_graphics(void)
  33. {
  34.  driver=DETECT; mode=0;
  35.  detectgraph(&driver,&mode);
  36.  if(driver==VGA) mode=VGAMED;
  37.  initgraph(&driver,&mode,"");
  38.  getpalette(&palette);
  39.  getpalette(&newpal);
  40. }
  41.  
  42. int cleanup_image(void)
  43. {
  44.  int i,j,num,x,y,k;
  45.  
  46.  if(cleancut<0) return;
  47.  setactivepage(LOADPAGE);
  48.  setvisualpage(ENHANCEPAGE);
  49.  for(x=minx;x<maxx;x++) {
  50.   for(y=miny;y<maxy;y++) {
  51.    if(getpixel(x,y)!=0) num=-1;
  52.     else num=0;
  53.    for(j=-1;j<2;j++) {
  54.     for(i=-1;i<2;i++) {
  55.      if(getpixel(x+i,y+j)!=0) num++;
  56.     }
  57.    }
  58.    if(num>cleancut) {
  59.     k=getpixel(x,y);
  60.     setactivepage(ENHANCEPAGE);
  61.     putpixel(x,y,k);
  62.     setactivepage(LOADPAGE);
  63.    }
  64.   }
  65.  }
  66.  k=ENHANCEPAGE; ENHANCEPAGE=LOADPAGE; LOADPAGE=k;
  67. }
  68.  
  69. void show_test_image(void)
  70. {
  71.  int i;
  72.  
  73.  minx=cmx; miny=cmy;
  74.  maxx=100+minx; maxy=100+miny;
  75.  setcolor(1);
  76.  moveto(minx,miny);
  77.  randomize();
  78.  for(i=0;i<20;i++)
  79.   lineto(random(100)+minx,random(100)+miny);
  80.  for(i=0;i<10;i++)
  81.   fillellipse(random(50)+25+minx,random(50)+25+miny,random(25),random(25));
  82. }
  83.  
  84. main()
  85. {
  86.  char fname[50];
  87.  int flag=0;
  88.  
  89.  load_convolution_matrix("matrix.dat");
  90.  printf(".CUT file (1) or test image (0)?");
  91.  scanf("%d",&flag);
  92.  flag= flag? 1:0;
  93.  if(flag) {
  94.   fflush(stdin);
  95.   printf("filename to process:");
  96.   gets(fname);
  97.  }
  98.  
  99.  printf("Delete pixels with x or fewer neighbors. x=");
  100.  scanf("%d",&cleancut);
  101.  if(cleancut>8) cleancut=8;
  102.  
  103.  init_graphics();
  104.  setactivepage(1); cleardevice();
  105.  setactivepage(0); cleardevice();
  106.  
  107.  setactivepage(LOADPAGE); setvisualpage(LOADPAGE);
  108.  if(flag) load_cut(fname);
  109.   else show_test_image();
  110.  cleanup_image();
  111.  
  112.  setvisualpage(ENHANCEPAGE);
  113.  convolve_image();
  114.  
  115.  swap_pictures();
  116.  restorecrtmode();
  117. }
  118.  
  119. int toggle_colors(char c)
  120. {
  121.  c=tolower(c);
  122.  c=c-'a';
  123.  if(c<0 || c>=palette.size) return 0;
  124.  newpal.colors[c]= palette.colors[c]-newpal.colors[c];
  125.  setpalette(c,newpal.colors[c]);
  126.  return 1;
  127. }
  128.  
  129. int swap_pictures(void)
  130. {
  131.  int mode=0;
  132.  char a;
  133.  
  134.  setvisualpage(LOADPAGE);
  135.  for(;;) {
  136.   a=getch();
  137.   if(a==27) return;
  138.   if(toggle_colors(a)) continue;
  139.   if(mode==0) setvisualpage(ENHANCEPAGE);
  140.   if(mode==1) setvisualpage(LOADPAGE);
  141.   mode=1-mode;
  142.  }
  143. }
  144.  
  145. int convolve_image(void)
  146. {
  147.  int i,j,k,nval;
  148.  int *vx, *vy, *c;
  149.  int colmax,offset,end,midy;
  150.  char **lines=NULL;
  151.  char *temp=NULL;
  152.  
  153.  offset=-minx+(cmx/2);
  154.  end=cmy-1; midy=cmy/2;
  155.  lines=(char **)malloc(cmy*sizeof(char *));
  156.  for(i=0;i<cmy;i++) lines[i]=(char *)malloc(sizeof(char)*(maxx-minx+cmx+1));
  157.  setactivepage(LOADPAGE);
  158.  for(j=-cmy/2;j<cmy/2;j++) {
  159.   for(i=minx-cmx/2;i<(maxx+cmx/2+1);i++) {
  160.    lines[j+midy][i+offset]=getpixel(i,j+miny);
  161.   }
  162.  }
  163.  colmax=getmaxcolor();
  164.  for(j=miny;j<maxy;j++) {
  165.   setactivepage(LOADPAGE);
  166.   for(i=j+cmy/2,k=minx-cmx/2,nval=maxx+cmx/2;k<nval;k++)
  167.    lines[end][k+offset]=getpixel(k,i);
  168.   for(i=minx;i<maxx;i++) {
  169.    /* Load & multiply neighbors into matrix */
  170.    setactivepage(LOADPAGE);
  171.    vx=vmat; vy=vmat+1; c=cmat; nval=0;
  172.    for(k=0;k<cmnum;k++) {
  173.     if(*c) nval+= lines[(*vy)+midy][i+(*vx)+offset]*(*c);
  174.     /* if(*c) nval+= getpixel(i+(*vx),j+(*vy)) * (*c); */
  175.     c++;
  176.     vx+=2; vy+=2;
  177.    }
  178.    /* Cut off values too high or too low */
  179.    if(nval<0) nval=0;
  180.    if(nval>colmax) nval=colmax;
  181.    /* Place new pixel value */
  182.    setactivepage(ENHANCEPAGE);
  183.    putpixel(i,j,nval);
  184.   }
  185.   if(kbhit()) { getch(); break; }
  186.   /* rotate line pointers */
  187.   temp=lines[0];
  188.   for(i=1;i<cmy;i++) lines[i-1]=lines[i];
  189.   lines[end]=temp;
  190.  }
  191.  for(i=0;i<cmy;i++) {
  192.   if(lines[i]!=NULL) free(lines[i]);
  193.  }
  194.  if(lines!=NULL) {
  195.   free(lines);
  196.  }
  197.  return;
  198. }
  199.  
  200. int build_offset_vectors(void)
  201. {
  202.  int *t;
  203.  int il,im,jl,jm,i,j;
  204.  
  205.  il=-cmx/2; im=cmx+il;
  206.  jl=-cmy/2; jm=cmy+jl;
  207.  t=vmat;
  208.  for(j=jl;j<jm;j++) {
  209.   for(i=il;i<im;i++) {
  210.    *t++=i; *t++=j;
  211.   }
  212.  }
  213. }
  214.  
  215. int load_convolution_matrix(char *fname)
  216. {
  217.  /* Layout of matrix file:
  218.      #x #y
  219.      x0y0 x1y0 ... xny1
  220.      .... .... ... ....
  221.      x0ym x1ym ... xnym
  222.  */
  223.  FILE *mf;
  224.  int *t;
  225.  int i,j,im,jm;
  226.  
  227.  if( (mf=fopen(fname,"rt"))==NULL ) {
  228.   printf("Cannot load matrix file.\n");
  229.   abort();
  230.  }
  231.  fscanf(mf,"%d%d",&im,&jm);
  232.  if( (im&1)==0 || (jm&1)==0 ) {
  233.   printf("Convolution matrix MUST have a center point.\n");
  234.   abort();
  235.  }
  236.  if( (cmat=(int *)calloc(im*jm,sizeof(int)))==NULL ) {
  237.   printf("Unable to calloc convolution matrix.\n");
  238.   abort();
  239.  }
  240.  if( (vmat=(int *)calloc(2*im*jm,sizeof(int)))==NULL ) {
  241.   printf("Unable to calloc offset vector matrix.\n");
  242.   abort();
  243.  }
  244.  cmx=im; cmy=jm; cmnum=im*jm;
  245.  t=cmat;
  246.  for(j=0;j<jm;j++) {
  247.   for(i=0;i<im;i++) {
  248.    if( fscanf(mf,"%d",t++)!=1 ) {
  249.     printf("Unable to read matrix.\n");
  250.     abort();
  251.    }
  252.   }
  253.  }
  254.  fclose(mf);
  255.  build_offset_vectors();
  256. }
  257.  
  258. int load_cut(char *fname)
  259. {
  260.  static unsigned char st[3000];
  261.  char *sp=st,*spend;
  262.  int stp=0;
  263.  int width,height;
  264.  FILE *fp;
  265.  int x,y,xl,yl;
  266.  int i,n,len,d,j;
  267.  
  268.  fp=fopen(fname,"rb");
  269.  width=getw(fp); height=getw(fp);
  270.  xl=cmx; yl=cmy;
  271.  minx=xl; miny=yl;
  272.  maxx=xl+width; maxy=yl+height;
  273.  if(maxy>(getmaxy()-cmy)) {
  274.   maxy=getmaxy()-cmy;
  275.   height=maxy-yl;
  276.  }
  277.  getw(fp);
  278.  y=yl-1;
  279.  for(sp=st,n=0;n<height;n++) {
  280.   stp=getw(fp);
  281.   for(sp=st,spend=st+stp;sp<spend;) *sp++=getc(fp);
  282.   sp=st; spend=sp+stp; x=xl; y++;
  283.   while(sp<spend) {
  284.    if(*((unsigned char *)sp)>0x80) {
  285.     len=(*sp++) & 0x7f;
  286.     if(!(*sp)) { x+=len; continue; }
  287.     setcolor(*sp++);
  288.     moveto(x,y);
  289.     linerel(len,0);
  290.     x+=len;
  291.     continue;
  292.    } else {
  293.     len=*sp++;
  294.     for(j=0;j<len;j++) putpixel(x++,y,*sp++);
  295.     continue;
  296.    }
  297.   }
  298.  }
  299.  fclose(fp);
  300. }
  301.  
  302.  
  303. Listing 2 - Matrix file
  304.  
  305. 3 3
  306. -1 -1 -1
  307. -1  8 -1
  308. -1 -1 -1
  309.