/* resize.cpp * */ #include <stdio.h> #include <math.h> #include "image.h" void resize_gray(IMAGE *in, IMAGE *out); void resize_rgb(IMAGE *in, IMAGE *out); int main(int argc, char *argv[]) { int magx, magy; IMAGE *in, *out; char *infile,*outfile; if (argc<3) { printf("usage: resize infile outfile [magx] [magy]\n"); printf("Image size expanded using bilinear interpolation.\n"); return -1; } infile=argv[1]; outfile=argv[2]; if (argc>3) sscanf(argv[3],"%d",&magx); else magx = 1; if (argc>4) sscanf(argv[4],"%d",&magy); else magy=magx; printf("input image: %s\n",infile); in = open_image(infile); if (!in) { printf("error opening image file\n"); return -1; } printf("image size: %d x %d\n",in->hlen,in->vlen); printf("pixel magnification: %d x %d\n\n",magx,magy); if (magx<=1 && magy<=1) { printf("no enlargement necessary\n"); return -1; } printf("output image: %s\n",outfile); out = make_image(outfile,in->hlen*magx,in->vlen*magy,in->type); if (!out) { printf("error creating output file\n"); return -1; } printf("image size: %d x %d\n",out->hlen,out->vlen); if (in->type==PIX_RGB) resize_rgb(in,out); else resize_gray(in,out); return 0; } inline float linint(double x, double x1, float fx1, float fx2) { return (float)((fx2-fx1)*(x-x1)+fx1); } /***** * C C RESIZE USES BI-LINEAR INTERPOLATION TO CHANGE THE PICTURE ON C WORKFILE WFIN TO A DIFFERENT SIZE PICTURE ON WFOUT. OUTPIX IS THE C NUMBER OF PIXELS/LINE ON THE NEW PICTURE, AND OUTLIN IS THE NUMBER C OF LINES C ******/ void resize_gray(IMAGE *in, IMAGE *out) { int i, j, ipntr; int x0, y0, x1; double fpix, flin, lp, ps, pp; pixel *buf, *buf1, *buf2, *buf3; float *fbuf1, *fbuf2, *fbuf3; float t1, t2; buf1 = make_buffer(in); buf2 = make_buffer(in); buf3 = make_buffer(out); /* compute incremental factors */ fpix = (double) (in->hlen-1)/ (double) (out->hlen-1); flin = (double) (in->vlen-1) / (double) (out->vlen-1); ps=0.0; lp=0.0; /* get window */ get_line(in,0,buf1,PIX_FLOAT); get_line(in,1,buf2,PIX_FLOAT); ipntr=1; for (j=0; j<out->vlen; j++) { if (lp>ipntr) { buf= buf1; buf1 = buf2; buf2 = buf; ipntr++; get_line(in,ipntr,buf2,PIX_FLOAT); } /* interpolate */ pp = ps; fbuf1 = (float *) buf1; fbuf2 = (float *) buf2; fbuf3 = (float *) buf3; for (i=0; i<out->hlen; i++, pp += fpix) { x0 = (int) floor(pp); y0 = (int) floor(lp); x1 = x0+1; if (pp==x0) fbuf3[i] = linint(lp,y0,fbuf1[x0],fbuf2[x0]); else if (pp==x1) fbuf3[i] = linint(lp,y0,fbuf1[x1],fbuf2[x1]); else { t1 = linint(pp,x0,fbuf1[x0],fbuf1[x1]); t2 = linint(pp,x0,fbuf2[x0],fbuf2[x1]); fbuf3[i] = linint(lp,y0,t1,t2); } } /* write line to output file */ put_line(out,j,buf3,PIX_FLOAT); lp += flin; } free_buffer(buf3); free_buffer(buf2); free_buffer(buf1); } struct rgb_color { float red, green, blue; void set(pixel val); pixel rgb(); void interp(double x, double x1, rgb_color &c1, rgb_color &c2); }; void rgb_color::set(pixel val) { red = GetRValue(val); green = GetGValue(val); blue = GetBValue(val); } inline pixel rgb_color::rgb() { return RGB((int)red,(int)green,(int)blue); } void rgb_color::interp(double x, double x1, rgb_color &c1, rgb_color &c2) { float dx = (float)(x-x1); red = (c2.red-c1.red)*dx + c1.red; green = (c2.green-c1.green)*dx + c1.green; blue = (c2,blue-c1.blue)*dx + c1.blue; } void resize_rgb(IMAGE *in, IMAGE *out) { int i, j, ipntr; int x0, y0, x1; double fpix, flin, lp, ps, pp; pixel *inpbuf, *outbuf; rgb_color val, t1, t2; rgb_color *buf, *buf1, *buf2; inpbuf = make_buffer(in); outbuf = make_buffer(in); buf1 = new rgb_color[in->hlen]; buf2 = new rgb_color[in->hlen]; /* compute incremental factors */ fpix = (double) (in->hlen-1)/ (double) (out->hlen-1); flin = (double) (in->vlen-1) / (double) (out->vlen-1); ps=0.0; lp=0.0; /* get window */ get_line(in,0,inpbuf,PIX_RGB); for (i=0; i<in->hlen; i++) buf1[i].set(inpbuf[i]); get_line(in,1,inpbuf,PIX_RGB); for (i=0; i<in->hlen; i++) buf2[i].set(inpbuf[i]); ipntr=1; for (j=0; j<out->vlen; j++) { if (lp>ipntr) { buf= buf1; buf1 = buf2; buf2 = buf; ipntr++; get_line(in,ipntr,inpbuf,PIX_RGB); for (i=0; i<in->hlen; i++) buf2[i].set(inpbuf[i]); } /* interpolate */ pp = ps; for (i=0; i<out->hlen; i++, pp += fpix) { x0 = (int) floor(pp); y0 = (int) floor(lp); x1 = x0+1; if (pp==x0) val.interp(lp,y0,buf1[x0],buf2[x0]); else if (pp==x1) val.interp(lp,y0,buf1[x1],buf2[x1]); else { t1.interp(pp,x0,buf1[x0],buf1[x1]); t2.interp(pp,x0,buf2[x0],buf2[x1]); val.interp(lp,y0,t1,t2); } outbuf[i] = val.rgb(); } /* write line to output file */ put_line(out,j,outbuf,PIX_RGB); lp += flin; } free_buffer(outbuf); free_buffer(inpbuf); delete [] buf1; delete [] buf2; }