int icv_resize(icv_image_t *bif, ICV_RESIZE_METHOD method, unsigned int out_width, unsigned int out_height, unsigned int factor) { ICV_IMAGE_VAL_INT(bif); switch (method) { case ICV_RESIZE_UNDERSAMPLE : return under_sample(bif, factor); case ICV_RESIZE_SHRINK : return shrink_image(bif, factor); case ICV_RESIZE_NINTERP : return ninterp(bif, out_width, out_height); case ICV_RESIZE_BINTERP : return binterp(bif, out_width, out_height); default : bu_log("icv_resize : Invalid Option to resize"); return -1; } }
/* * Scale a file of pixels to a different size. * * To scale down we make a square pixel assumption. * We will preserve the amount of light energy per unit area. * To scale up we use bilinear interpolation. */ int scale(FILE *ofp, int ix, int iy, int ox, int oy) { int i, j, k, l; double pxlen, pylen; /* # old pixels per new pixel */ double xstart, xend, ystart, yend; /* edges of new pixel in old coordinates */ double xdist, ydist; /* length of new pixel sides in old coord */ double sum; unsigned char *op; pxlen = (double)ix / (double)ox; pylen = (double)iy / (double)oy; if ((pxlen < 1.0 && pylen > 1.0) || (pxlen > 1.0 && pylen < 1.0)) { fprintf(stderr, "bwscale: can't stretch one way and compress another!\n"); return -1; } if (pxlen < 1.0 || pylen < 1.0) { /* scale up */ if (rflag) { /* nearest neighbor interpolate */ ninterp(ofp, ix, iy, ox, oy); } else { /* bilinear interpolate */ binterp(ofp, ix, iy, ox, oy); } return 0; } /* for each output pixel */ for (j = 0; j < oy; j++) { size_t ret; ystart = j * pylen; yend = ystart + pylen; op = outbuf; for (i = 0; i < ox; i++) { xstart = i * pxlen; xend = xstart + pxlen; sum = 0.0; /* * For each pixel of the original falling * inside this new pixel. */ for (l = FLOOR(ystart); l < CEILING(yend); l++) { /* Make sure we have this row in the buffer */ bufy = l - buf_start; if (bufy < 0 || bufy >= buflines) { fill_buffer(l); bufy = l - buf_start; } /* Compute height of this row */ if ((double)l < ystart) ydist = CEILING(ystart) - ystart; else ydist = MIN(1.0, yend - (double)l); for (k = FLOOR(xstart); k < CEILING(xend); k++) { /* Compute width of column */ if ((double)k < xstart) xdist = CEILING(xstart) - xstart; else xdist = MIN(1.0, xend - (double)k); /* Add this pixels contribution */ /* sum += old[l][k] * xdist * ydist; */ sum += buffer[bufy * scanlen + k] * xdist * ydist; } } *op++ = (int)(sum / (pxlen * pylen)); if (op > (outbuf+scanlen)) bu_bomb("unexpected buffer overrun"); } ret = fwrite(outbuf, 1, ox, ofp); if (ret != (size_t)ox) perror("fwrite"); } return 1; }