#include<stdlib.h> #include<stdio.h> #include<graphics.h> #include<alloc.h> #include<ctype.h> int load_cut(char *fname); int load_convolution_matrix(char *fname); int convolve_image(void); int swap_pictures(void); int minx,maxx,miny,maxy; int LOADPAGE=0; int ENHANCEPAGE=1; int *cmat, *pmat, *vmat; int cmx,cmy,cmnum; struct palettetype palette,newpal; int driver,mode; int cleancut=-1; int init_graphics(void) { driver=DETECT; mode=0; detectgraph(&driver,&mode); if(driver==VGA) mode=VGAMED; initgraph(&driver,&mode,""); getpalette(&palette); getpalette(&newpal); } int cleanup_image(void) { int i,j,num,x,y,k; if(cleancut<0) return; setactivepage(LOADPAGE); setvisualpage(ENHANCEPAGE); for(x=minx;x<maxx;x++) { for(y=miny;y<maxy;y++) { if(getpixel(x,y)!=0) num=-1; else num=0; for(j=-1;j<2;j++) { for(i=-1;i<2;i++) { if(getpixel(x+i,y+j)!=0) num++; } } if(num>cleancut) { k=getpixel(x,y); setactivepage(ENHANCEPAGE); putpixel(x,y,k); setactivepage(LOADPAGE); } } } k=ENHANCEPAGE; ENHANCEPAGE=LOADPAGE; LOADPAGE=k; } void show_test_image(void) { int i; minx=cmx; miny=cmy; maxx=100+minx; maxy=100+miny; setcolor(1); moveto(minx,miny); randomize(); for(i=0;i<20;i++) lineto(random(100)+minx,random(100)+miny); for(i=0;i<10;i++) fillellipse(random(50)+25+minx,random(50)+25+miny,random(25),random(25)); } main() { char fname[50]; int flag=0; load_convolution_matrix("matrix.dat"); printf(".CUT file (1) or test image (0)?"); scanf("%d",&flag); flag= flag? 1:0; if(flag) { fflush(stdin); printf("filename to process:"); gets(fname); } printf("Delete pixels with x or fewer neighbors. x="); scanf("%d",&cleancut); if(cleancut>8) cleancut=8; init_graphics(); setactivepage(1); cleardevice(); setactivepage(0); cleardevice(); setactivepage(LOADPAGE); setvisualpage(LOADPAGE); if(flag) load_cut(fname); else show_test_image(); cleanup_image(); setvisualpage(ENHANCEPAGE); convolve_image(); swap_pictures(); restorecrtmode(); } int toggle_colors(char c) { c=tolower(c); c=c-'a'; if(c<0 || c>=palette.size) return 0; newpal.colors[c]= palette.colors[c]-newpal.colors[c]; setpalette(c,newpal.colors[c]); return 1; } int swap_pictures(void) { int mode=0; char a; setvisualpage(LOADPAGE); for(;;) { a=getch(); if(a==27) return; if(toggle_colors(a)) continue; if(mode==0) setvisualpage(ENHANCEPAGE); if(mode==1) setvisualpage(LOADPAGE); mode=1-mode; } } int convolve_image(void) { int i,j,k,nval; int *vx, *vy, *c; int colmax,offset,end,midy; char **lines=NULL; char *temp=NULL; offset=-minx+(cmx/2); end=cmy-1; midy=cmy/2; lines=(char **)malloc(cmy*sizeof(char *)); for(i=0;i<cmy;i++) lines[i]=(char *)malloc(sizeof(char)*(maxx-minx+cmx+1)); setactivepage(LOADPAGE); for(j=-cmy/2;j<cmy/2;j++) { for(i=minx-cmx/2;i<(maxx+cmx/2+1);i++) { lines[j+midy][i+offset]=getpixel(i,j+miny); } } colmax=getmaxcolor(); for(j=miny;j<maxy;j++) { setactivepage(LOADPAGE); for(i=j+cmy/2,k=minx-cmx/2,nval=maxx+cmx/2;k<nval;k++) lines[end][k+offset]=getpixel(k,i); for(i=minx;i<maxx;i++) { /* Load & multiply neighbors into matrix */ setactivepage(LOADPAGE); vx=vmat; vy=vmat+1; c=cmat; nval=0; for(k=0;k<cmnum;k++) { if(*c) nval+= lines[(*vy)+midy][i+(*vx)+offset]*(*c); /* if(*c) nval+= getpixel(i+(*vx),j+(*vy)) * (*c); */ c++; vx+=2; vy+=2; } /* Cut off values too high or too low */ if(nval<0) nval=0; if(nval>colmax) nval=colmax; /* Place new pixel value */ setactivepage(ENHANCEPAGE); putpixel(i,j,nval); } if(kbhit()) { getch(); break; } /* rotate line pointers */ temp=lines[0]; for(i=1;i<cmy;i++) lines[i-1]=lines[i]; lines[end]=temp; } for(i=0;i<cmy;i++) { if(lines[i]!=NULL) free(lines[i]); } if(lines!=NULL) { free(lines); } return; } int build_offset_vectors(void) { int *t; int il,im,jl,jm,i,j; il=-cmx/2; im=cmx+il; jl=-cmy/2; jm=cmy+jl; t=vmat; for(j=jl;j<jm;j++) { for(i=il;i<im;i++) { *t++=i; *t++=j; } } } int load_convolution_matrix(char *fname) { /* Layout of matrix file: #x #y x0y0 x1y0 ... xny1 .... .... ... .... x0ym x1ym ... xnym */ FILE *mf; int *t; int i,j,im,jm; if( (mf=fopen(fname,"rt"))==NULL ) { printf("Cannot load matrix file./n"); abort(); } fscanf(mf,"%d%d",&im,&jm); if( (im&1)==0 || (jm&1)==0 ) { printf("Convolution matrix MUST have a center point./n"); abort(); } if( (cmat=(int *)calloc(im*jm,sizeof(int)))==NULL ) { printf("Unable to calloc convolution matrix./n"); abort(); } if( (vmat=(int *)calloc(2*im*jm,sizeof(int)))==NULL ) { printf("Unable to calloc offset vector matrix./n"); abort(); } cmx=im; cmy=jm; cmnum=im*jm; t=cmat; for(j=0;j<jm;j++) { for(i=0;i<im;i++) { if( fscanf(mf,"%d",t++)!=1 ) { printf("Unable to read matrix./n"); abort(); } } } fclose(mf); build_offset_vectors(); } int load_cut(char *fname) { static unsigned char st[3000]; char *sp=st,*spend; int stp=0; int width,height; FILE *fp; int x,y,xl,yl; int i,n,len,d,j; fp=fopen(fname,"rb"); width=getw(fp); height=getw(fp); xl=cmx; yl=cmy; minx=xl; miny=yl; maxx=xl+width; maxy=yl+height; if(maxy>(getmaxy()-cmy)) { maxy=getmaxy()-cmy; height=maxy-yl; } getw(fp); y=yl-1; for(sp=st,n=0;n<height;n++) { stp=getw(fp); for(sp=st,spend=st+stp;sp<spend;) *sp++=getc(fp); sp=st; spend=sp+stp; x=xl; y++; while(sp<spend) { if(*((unsigned char *)sp)>0x80) { len=(*sp++) & 0x7f; if(!(*sp)) { x+=len; continue; } setcolor(*sp++); moveto(x,y); linerel(len,0); x+=len; continue; } else { len=*sp++; for(j=0;j<len;j++) putpixel(x++,y,*sp++); continue; } } } fclose(fp); } |