#include #include #include #include #include "mat_util.h" #include "ppm.h" // program gets passed ppm image filename and blur amount void usage(); void blurfunc( Var *Image, int blursize); int main(int argc, char *argv[]) { char infilename[2048]; // hopefully path and filename not greater than 2K char outfilename[2048]; int blursize; Var myImage; if (argc != 4) { usage(); exit(0); } // first character of string only //(subtract ascii value of zero) ... blursize = *argv[2] - '0'; blursize = atoi(argv[2]); sprintf(infilename, "%s", argv[1]); sprintf(outfilename, "%s", argv[3]); fprintf(stderr,"%s: infilename = %s, blursize = %d; ... \n",argv[0],infilename,blursize); // if blursize is not odd if ((blursize % 2) == 0) { usage(); exit(0); } // load ppm file into Image load_ppm_file(infilename, &myImage); switch( myImage.magic_number ) { case GREY_PGM :fprintf(stderr,"%s is a pgm\n", infilename); break; case RGB_PPM :fprintf(stderr,"%s is a ppm\n", infilename); break; case GREY_PDM :fprintf(stderr,"%s is a grayscale pdm\n", infilename); break; case RGB_PDM :fprintf(stderr,"%s is a color pdm\n", infilename); break; case GREY_PLM :fprintf(stderr,"%s is a greyscale plm\n", infilename); break; case RGB_PLM :fprintf(stderr,"%s is a color plm\n", infilename); break; default :fprintf(stderr,"blur couldn't determine type of input\n"); return -1; } // blur it blurfunc(&myImage, blursize); // write image back to disk save_pgm_file(&myImage, outfilename); return(1); } void blurfunc( Var *image, int blursize) { Var *ANS, *ANS2; int m,n,k,i; Image tmp; int channels = image->channels; int width, halfblur; ANS = (Var *)calloc(1, sizeof(Var)); ANS2 = (Var *)calloc(1, sizeof(Var)); init_var(ANS, image->name, image->M, image->N, IMAGE, channels); init_var(ANS2, image->name, image->M, image->N, IMAGE, channels); if (channels == GREY_SCALE) { // blur in the across direction (easy even with small amount of cache): for( m=0 ; mM ; m++ ) { for( n=0 ; nN ; n++ ) { tmp = 0; if( nimage[m*image->N +n +k]; ANS->image[m*image->N + n] = (tmp/(n+1+blursize/2)); } else if( n>=image->N-blursize/2 ) // right edge { for( k=-blursize/2 ; kN-n ; k++ ) tmp+=image->image[m*image->N +n +k]; ANS->image[m*image->N + n] = (tmp/(image->N-n+blursize/2)); } else { for( k=-blursize/2 ; k<=blursize/2 ; k++ ) tmp += image->image[m*image->N + n + k]; ANS->image[m*image->N + n] = (tmp/blursize); } } } //blur in the down direction (same order, in case small number lines in cache): for( m=0 ; mM ; m++ ) { for( n=0 ; nN ; n++ ) { tmp = 0; // CLA (clear the accumulator) if( mimage[(m+k)*image->N +n]; ANS2->image[m*image->N + n] = (tmp/(m+1+blursize/2)); } else if( m>=image->M-blursize/2 ) // bottom edge { for( k=-blursize/2 ; kM-m ; k++ ) tmp+=ANS->image[(k+m)*image->N +n]; ANS2->image[m*image->N + n] = (tmp/(image->M-m+blursize/2)); } else // not at edges { tmp = 0; for( k=-blursize/2 ; k<=blursize/2 ; k++ ) tmp += ANS->image[(m+k)*image->N + n]; ANS2->image[m*image->N + n] = (tmp/blursize); } } } } else if (channels == RGB24) { width = image->N*channels; halfblur = blursize/2*channels; // blur in the across direction (easy even with small amount of cache): for( m=0 ; mM ; m++ ) { for( n=0 ; nimage[m*width +k]; ANS->image[m*width + n] = (tmp/i); } else if( n>=width-halfblur ) // right edge { for( k=-halfblur, i=0; kimage[m*width +n +k]; ANS->image[m*width + n] = (tmp/i); } else { for( k=-halfblur ; k<=halfblur ; k+=channels ) tmp += image->image[m*width + n + k]; ANS->image[m*width + n] = (tmp/blursize); } } } //blur in the down direction (same order, in case small number lines in cache): for( m=0 ; mM ; m++ ) { for( n=0 ; nimage[(m+k)*width +n]; ANS2->image[m*width + n] = (tmp/(m+1+blursize/2)); } else if( m>=image->M-blursize/2 ) // bottom edge { for( k=-blursize/2 ; kM-m ; k++ ) tmp+=ANS->image[(k+m)*width +n]; ANS2->image[m*width + n] = (tmp/(image->M-m+blursize/2)); } else // not at edges { tmp = 0; for( k=-blursize/2 ; k<=blursize/2 ; k++ ) tmp += ANS->image[(m+k)*width + n]; ANS2->image[m*width + n] = (tmp/blursize); } } } } /* - - Copy answer to original image - - */ copy_image(ANS2, image); /* - - Free OLD image - - */ free(ANS2->image); free(ANS->image); } void usage() { fprintf(stderr, "Usage: ./blur v001.pgm 7 deleteme.pgm\n"); fprintf(stderr, " : ./blur v001.ppm 7 deleteme.ppm\n"); fprintf(stderr, " : ./blur v001.plm 7 deleteme.plm\n"); fprintf(stderr, "only supports odd valued blur radii\n"); }