home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_08_08 / 8n08098a < prev    next >
Text File  |  1990-07-18  |  7KB  |  303 lines

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