#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
static void
resample(Memimage *dst, Rectangle r, Memimage *src, Rectangle sr, int bilinear)
{
Point sp, dp;
Point _sp, qp;
Point ssize, dsize;
uchar *pdst0, *pdst, *psrc0, *psrc;
ulong s00, s01, s10, s11;
int tx, ty, b, bpp, bpl;
ssize = subpt(subpt(sr.max, sr.min), Pt(1,1));
dsize = subpt(subpt(r.max, r.min), Pt(1,1));
pdst0 = byteaddr(dst, r.min);
bpp = src->depth/8;
bpl = src->width*sizeof(int);
qp.x = (ssize.x<<12)/dsize.x;
qp.y = (ssize.y<<12)/dsize.y;
_sp.y = sr.min.y<<12;
for(dp.y=0; dp.y<=dsize.y; dp.y++){
sp.y = _sp.y>>12;
ty = _sp.y&0xFFF;
if(!bilinear && ty >= 0x800)
sp.y++;
pdst = pdst0;
sp.x = sr.min.x;
psrc0 = byteaddr(src, sp);
_sp.x = 0;
for(dp.x=0; dp.x<=dsize.x; dp.x++){
sp.x = _sp.x>>12;
tx = _sp.x&0xFFF;
psrc = psrc0 + sp.x*bpp;
if(!bilinear){
if(tx >= 0x800)
psrc += bpp;
for(b=0; b<bpp; b++)
pdst[b] = psrc[b];
}else{
s00 = (0x1000-tx)*(0x1000-ty);
s01 = tx*(0x1000-ty);
s10 = (0x1000-tx)*ty;
s11 = tx*ty;
for(b=0; b<bpp; b++){
pdst[b] = ( s11*psrc[bpl+bpp+b]
+s10*psrc[bpl+b]
+s01*psrc[bpp+b]
+s00*psrc[b]
) >>24;
}
}
pdst += bpp;
_sp.x += qp.x;
}
pdst0 += dst->width*sizeof(int);
_sp.y += qp.y;
}
}
void
usage(void)
{
sysfatal("Usage: %s -s width height [-b] [image]\n", argv0);
}
void
main(int argc, char **argv)
{
Memimage *im, *nim;
Rectangle r = {0, 0, 0, 0};
int bilinear= 0;
ARGBEGIN{
case 'b':
bilinear++;
break;
case 's':
r.max.x = atoi(EARGF(usage()));
r.max.y = atoi(EARGF(usage()));
break;
default:
usage();
}ARGEND
if(argc != 0 && argc != 1)
usage();
memimageinit();
im = readmemimage(open(argv[0]? argv[0] : "/fd/0", OREAD));
nim = allocmemimage(r, im->chan);
resample(nim, r, im, im->r, bilinear);
writememimage(1, nim);
exits(0);
}
|