/* distort.cpp * */ #include <stdio.h> #include <math.h> #include "image.h" /* * x = (i-xcen)*dx * y = (ycen-j)*dy * */ class Image_Scale { public: Image_Scale(IMAGE *ip); double dx, dy; int xcen, ycen; double x(int i) { return (i-xcen)*dx; } double y(int j) { return (ycen-j)*dy; } int nx(double x) { return (int)(xcen + x/dx); } int ny(double y) { return (int)(ycen - y/dy); } }; Image_Scale::Image_Scale(IMAGE *ip) { dx = dy = 4.0/(ip->hlen+ip->vlen); xcen = ip->hlen/2; ycen = ip->vlen/2; } void distort(IMAGE *in, IMAGE *out, double distortion); // defined in copyimg.cpp void copy_image(IMAGE *src, IMAGE *dst); int main(int argc, char *argv[]) { IMAGE *in, *out, *tmp; char *infile,*outfile; double distortion; if (argc<4) { printf("usage: distortion infile outfile distortion\n"); return -1; } infile=argv[1]; outfile=argv[2]; sscanf(argv[3]," %lf",&distortion); in = open_image(infile); if (!in) return -1; printf("input image: %s\n",infile); printf("image size: %d x %d\n",in->hlen,in->vlen); tmp = make_image(NULL, in->hlen, in->vlen,in->type); if (!in) return -1; printf("copying input to local memory . . .\n"); copy_image(in,tmp); printf("distortion: %g\n",distortion); out = make_image(outfile,in->hlen,in->vlen,in->type); if (!out) return -1; printf("distorting image . . .\n"); distort(tmp,out,distortion); printf("output image: %s\n",outfile); printf("image size: %d x %d\n",out->hlen,out->vlen); return 0; } void distort(IMAGE *in, IMAGE *out, double distortion) { pixel *buf, *bp; int i,j; int nx, ny; double mag, base; double vin[2]; double vout[2]; double hsq; Image_Scale uv(out), xy(in); buf = make_buffer(out); vin[0] = vin[1] = 0.0; base = (distortion<0.0? 1.0 - distortion: 1.0 - 2.0*distortion); for (j=0; j<out->vlen; j++) { vout[1] = uv.y(j); bp = buf; for (i=0; i<out->hlen; i++, bp++) { *bp = 0; vout[0] = uv.x(i); hsq = vout[0]*vout[0]+vout[1]*vout[1]; mag = base+distortion*hsq; vin[0] = vout[0]/mag; vin[1] = vout[1]/mag; nx = xy.nx(vin[0]); if (nx<0 || nx>=in->hlen) continue; ny = xy.ny(vin[1]); if (ny<0 || ny>=in->vlen) continue; *bp = in->get_pixel(nx, ny, in->type); } put_line(out,j,buf,in->type); } free_buffer(buf); }