#include #include #include #include /* * Read a P6 PPM file on standard input, and write a P6 PPM file on standard output. * The output file will have the object centered, with the assumption that any * pixels with values >= 10% R/G/B are part of the object, and elsewise are background */ Usage() { fprintf(stderr,"ppmcentre [infile] [outfile]\n"); fprintf(stderr,"Infile is either a PPM file or '-' for standard input. \n"); fprintf(stderr,"Outfile is a PPM file.\n"); fprintf(stderr,"If outfile is omitted, standard output is used.\n"); fprintf(stderr,"If both Infile and Outfile are omitted, standard input and output are used\n"); } main(int argc, char *argv[]) { int width,height,depth,colourmax; char type[10]; FILE *in = stdin; FILE *out = stdout; int i,err; int bufsize = 0; char *buffer,*outbuffer; #ifdef WIN32 // Make stdout/stdin binary mode setmode(fileno(stdin), O_BINARY); setmode(fileno(stdout), O_BINARY); #endif // how many ways are there of asking for help?? if (argc == 2) { if (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-?") || !strcmp(argv[1],"-h") || !strcmp(argv[1],"/?")) { Usage(); exit(0); } // 1 argument, must be input file if (!strcmp(argv[1],"-")) in = stdin; else in = fopen(argv[1],"rb"); out = fdopen(1,"wb"); } else if (argc == 3) { // Both input and output are specified if (!strcmp(argv[1] ,"-")) in = stdin; else in = fopen(argv[1],"rb"); out = fopen(argv[2],"wb"); } if (in == NULL) { fprintf(stderr,"ppmcenter: cannot open input file\n"); Usage(); exit(1); } if (out == NULL) { fprintf(stderr,"ppmcenter: cannot open output file\n"); Usage(); exit(1); } /* * Read the input */ type[0] = 0; ppm_header(in,type,&width,&height,&colourmax); if (strcmp(type,"P6")) { fprintf(stderr,"Type '%s' not understood\n",type); Usage(); exit(1); } fprintf(stderr,"Image is %dx%d\n",width,height); /* * Allocate the buffer and load the data */ bufsize = width * height * 3; buffer = (char *)malloc(bufsize); if (buffer == NULL) { fprintf(stderr,"Cannot malloc buffer of %d bytes\n",bufsize); exit(1); } err = fread(buffer,1,bufsize,in); if (err != bufsize) { fprintf(stderr,"Error in reading data, only read %d bytes of %d\n",err,bufsize); exit(1); } outbuffer = (char *)malloc(bufsize); if (outbuffer == NULL) { fprintf(stderr,"Cannot malloc outbuffer of %d bytes\n",bufsize); exit(1); } if (! process(width,height,buffer,outbuffer)) { fprintf(stderr,"Error in processing, no output generated\n"); exit(1); } fprintf(out,"P6\n%d %d\n%d\n",width,height,colourmax); fwrite(outbuffer,1,bufsize,out); fflush(out); exit(0); } int process(int width, int height, char *in, char *out) { int x,y; int count; // count of significant pixels int x_total, y_total; int x_avg,y_avg,xc,yc; int size = width * height * 3; char *ptr = in; int i,r,g,b; count=0; x_total = y_total = 0; for(y=0; y 50) { x_total += x; y_total += y; count++; } } } if (count == 0) { fprintf(stderr,"Could not find anything in the frame\n"); return(0); } if (count < 250) { fprintf(stderr,"Not enough pixels found. Found %d\n",count); return(0); } x_avg = x_total / count; y_avg = y_total / count; fprintf(stderr,"Object centre at (%d,%d), size %d pixels\n",x_avg,y_avg,count); // Fill the buffer with zeroes for(i=0; i=height) continue; for (x=-200; x<=200; ++x) { int xi,xo,yo,oi,oo; xi = x + x_avg; // Skip if source off the image if (xi<0 || xi>=width) continue; // Input Offset oi = (yi * width + xi) * 3; // Output Offset xo = x + xc; yo = y + yc; oo = (yo * width + xo) * 3; // It's an error if the dest is off the image if (xo<0 || xo>=width || yo<0 || yo>=height) { fprintf(stderr, "Oops - dest (%d,%d) is off the image!\n",xo,yo); return(0); } //printf("(%d,%d) -> (%d,%d)\n",xi,yi,xo,yo); out[oo] = in[oi]; out[oo+1] = in[oi+1]; out[oo+2] = in[oi+2]; } } return(1); } int ppm_header(FILE *in,char *type, int *width, int *height, int *colours) { int ch,i,incomment; char buf[32]; type[0]=0; *width=0; *height=0; *colours=0; incomment=0; i=0; while(1) { switch(ch=getc(in)) { case EOF: return 1; case '#': incomment=1; break; case ' ': case '\t': if (incomment) break; case '\n': case '\r': if (incomment) {incomment=0; break;} if (type[0]==0) { strcpy(type,buf); if (type[0]!='P') return 1; if (type[1]!='3' && type[1]!='6') return 1; i=0; buf[0]=0; break; } if (*width==0) {*width=atoi(buf); i=0; buf[0]=0; break;} if (*height==0) {*height=atoi(buf); i=0; buf[0]=0; break;} if (*colours==0) {*colours=atoi(buf); return(0); break;} default: buf[i++]=ch; buf[i]=0; break; } } return 1; }