/*** reduce.cpp * * reduce image size by pixel averaging. * ***/ #include <stdio.h> #include <stdlib.h> #include "image.h" #include "errmsg.h" void reduce_gray(IMAGE *in, IMAGE *out, int magx, int magy); void reduce_rgb(IMAGE *in, IMAGE *out, int magx, int magy); int main(int argc, char *argv[]) { int magx, magy; IMAGE *in, *out; char *infile,*outfile; if (argc<4) { printf("usage: reduce infile outfile magx [magy]\n"); return -1; } infile=argv[1]; outfile=argv[2]; sscanf(argv[3],"%d",&magx); if (argc>4) sscanf(argv[4],"%d",&magy); else magy=magx; 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); printf("reduction factors: %d x %d\n\n",magx,magy); if (magx<1 || magy < 1) { printf("illegal reduction factors\n"); return -1; } if (magx == 1 && magy == 1) { printf("no reduction required\n"); return -1; } out = make_image(outfile,in->hlen/magx,in->vlen/magy,in->type); printf("output image: %s\n",outfile); 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) reduce_rgb(in, out, magx, magy); else reduce_gray(in,out,magx,magy); return 0; } void reduce_gray(IMAGE *in, IMAGE *out, int magx, int magy) { pixel *buf1, *buf2; float *inbuf, *outbuf, sum, magxy; int i, j, kx, ky, nx, ny; magxy = (float) magx * (float) magy; buf1 = make_buffer(in); buf2 = make_buffer(in); inbuf = (float *) buf1; outbuf = (float *) buf2; for (j=ny=0; j<out->vlen; j++) { // sum over rows get_line(in,ny,buf2,PIX_FLOAT); ny++; for (ky=1; ky<magy; ky++, ny++) { get_line(in,ny,buf1,PIX_FLOAT); for (i=0; i<in->hlen; i++) { outbuf[i] += inbuf[i]; } } for (i=nx=0; i<out->hlen; i++) { // sum over columns sum = outbuf[nx]; nx++; for (kx=1; kx<magx; kx++, nx++) { sum += outbuf[nx]; } outbuf[i] = sum/magxy; } put_line(out,j,buf2,PIX_FLOAT); } free_buffer(buf1); free_buffer(buf2); } void reduce_rgb(IMAGE *in, IMAGE *out, int magx, int magy) { pixel *buf, val; double *red, *grn, *blu; double redtot, grntot, blutot, magxy; int i, j, kx, ky, nx, ny; magxy = (float) magx * (float) magy; buf = make_buffer(in); red = new double[in->hlen]; grn = new double[in->hlen]; blu = new double[in->hlen]; if (!red || !grn || !blu) errmsg("alloc error in reduce_rgb"); for (j=ny=0; j<out->vlen; j++) { // sum over rows get_line(in,ny,buf,PIX_RGB); for (i=0; i<in->hlen; i++) { val = buf[i]; red[i] = GetRValue(val); grn[i] = GetGValue(val); blu[i] = GetBValue(val); } ny++; for (ky=1; ky<magy; ky++, ny++) { get_line(in,ny,buf,PIX_RGB); for (i=0; i<in->hlen; i++) { val = buf[i]; red[i] += GetRValue(val); grn[i] += GetGValue(val); blu[i] += GetBValue(val); } } for (i=nx=0; i<out->hlen; i++) { // sum over columns redtot = red[nx]; grntot = grn[nx]; blutot = blu[nx]; nx++; for (kx=1; kx<magx; kx++, nx++) { redtot += red[nx]; grntot += grn[nx]; blutot += blu[nx]; } redtot /= magxy; grntot /= magxy; blutot /= magxy; buf[i] = RGB((int)redtot,(int)grntot,(int)blutot); } put_line(out,j,buf,PIX_RGB); } free_buffer(buf); delete [] red; delete [] grn; delete [] blu; }