#include "image.h" #include Point fmulpt(Point p, double f) { return Pt(p.x*f, p.y*f); } int linesz(ImgHdr h) { return Dx(h.r) * chantodepth(h.chan)/8; } void scaleline(uchar *dst, uchar *src, int dstlen, int nc, double s) { int x, c; for(x = 0; x < dstlen; x++) { for(c = 0; c < nc; c++) dst[x*nc + c] = src[(int)(x/s)*nc + c]; } } void usage(void) { fprint(2, "usage: %s scale\n", argv0); exits("usage"); } void main(int argc, char **argv) { Biobuf bdst, bsrc; double scale; ImgHdr hdst, hsrc; uchar *buf, *src, *dst; int nc, n, dstline, srcline; ARGBEGIN { default: usage(); } ARGEND if(argc != 1) usage(); scale = atof(argv[0]); if(fmtinstall('H', Hfmt) < 0) sysfatal("fmtinstall"); if(Binit(&bsrc, 0, OREAD) < 0 || Binit(&bdst, 1, OWRITE) < 0) sysfatal("Binit"); if(readimghdr(0, &hsrc) < 0) sysfatal("header: %r"); hdst = (ImgHdr){0, hsrc.chan, Rpt(fmulpt(hsrc.r.min, scale), fmulpt(hsrc.r.max, scale))}; if(!eqrect(hdst.r, canonrect(hdst.r))) sysfatal("bad scale"); Bprint(&bdst, "%H", hdst); nc = chantodepth(hsrc.chan)/8; if((buf = malloc(linesz(hdst) + linesz(hsrc))) == nil) sysfatal("alloc: %r"); dst = buf; src = buf + linesz(hdst); srcline = -1; for(dstline = 0; dstline < Dy(hdst.r); dstline++) { if(srcline < (int)(dstline/scale)) { for(; srcline < (int)(dstline/scale); srcline++) { if((n = Bread(&bsrc, src, linesz(hsrc))) < 0) sysfatal("read src: %r"); else if(n == 0) sysfatal("unexpected eof: %d/%d", srcline, Dy(hsrc.r)); } scaleline(dst, src, Dx(hdst.r), nc, scale); } if(Bwrite(&bdst, dst, linesz(hdst)) != linesz(hdst)) sysfatal("write dst: %r"); } exits(nil); }