#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>

#define K2 7	/* from -.7 to +.7 inclusive, meaning .2 into each adjacent pixel */
#define NK (2*K2+1)
double K[NK];

double
fac(int L)
{
	int i, f;

	f = 1;
	for(i=L; i>1; --i)
		f *= i;
	return f;
}

/* 
 * i0(x) is the modified Bessel function, Σ (x/2)^2L / (L!)²
 * There are faster ways to calculate this, but we precompute
 * into a table so let's keep it simple.
 */
double
i0(double x)
{
	double v;
	int L;

	v = 1.0;
	for(L=1; L<10; L++)
		v += pow(x/2., 2*L)/pow(fac(L), 2);
	return v;
}

double
kaiser(double x, double tau, double alpha)
{
	if(fabs(x) > tau)
		return 0.;
	return i0(alpha*sqrt(1-(x*x/(tau*tau))))/i0(alpha);
}

void
usage(void)
{
	fprint(2, "usage: resample [-x xsize] [-y ysize] [imagefile]\n");
	fprint(2, "\twhere size is an integer or a percentage in the form 25%%\n");
	exits("usage");
}

int
getint(char *s, int *percent)
{
	if(s == nil)
		usage();
	*percent = (s[strlen(s)-1] == '%');
	if(*s == '+')
		return atoi(s+1);
	if(*s == '-')
		return -atoi(s+1);
	return atoi(s);
}

void
resamplex(uchar *in, int off, int d, int inx, uchar *out, int outx)
{
	int i, x, k;
	double X, xx, v, rat;


	rat = (double)inx/(double)outx;
	for(x=0; x<outx; x++){
		if(inx == outx){
			/* don't resample if size unchanged */
			out[off+x*d] = in[off+x*d];
			continue;
		}
		v = 0.0;
		X = x*rat;
		for(k=-K2; k<=K2; k++){
			xx = X + rat*k/10.;
			i = xx;
			if(i < 0)
				i = 0;
			if(i >= inx)
				i = inx-1;
			v += in[off+i*d] * K[K2+k];
		}
		out[off+x*d] = v;
	}
}

void
resampley(uchar **in, int off, int iny, uchar **out, int outy)
{
	int y, i, k;
	double Y, yy, v, rat;

	rat = (double)iny/(double)outy;
	for(y=0; y<outy; y++){
		if(iny == outy){
			/* don't resample if size unchanged */
			out[y][off] = in[y][off];
			continue;
		}
		v = 0.0;
		Y = y*rat;
		for(k=-K2; k<=K2; k++){
			yy = Y + rat*k/10.;
			i = yy;
			if(i < 0)
				i = 0;
			if(i >= iny)
				i = iny-1;
			v += in[i][off] * K[K2+k];
		}
		out[y][off] = v;
	}

}

int
max(int a, int b)
{
	if(a > b)
		return a;
	return b;
}

Memimage*
resample(int xsize, int ysize, Memimage *m)
{
	int i, j, bpl, nchan;
	Memimage *new;
	uchar **oscan, **nscan;

	new = allocmemimage(Rect(0, 0, xsize, ysize), m->chan);
	if(new == nil)
		sysfatal("can't allocate new image: %r");

	oscan = malloc(Dy(m->r)*sizeof(uchar*));
	nscan = malloc(max(ysize, Dy(m->r))*sizeof(uchar*));
	if(oscan == nil || nscan == nil)
		sysfatal("can't allocate: %r");

	/* unload original image into scan lines */
	bpl = bytesperline(m->r, m->depth);
	for(i=0; i<Dy(m->r); i++){
		oscan[i] = malloc(bpl);
		if(oscan[i] == nil)
			sysfatal("can't allocate: %r");
		j = unloadmemimage(m, Rect(m->r.min.x, m->r.min.y+i, m->r.max.x, m->r.min.y+i+1), oscan[i], bpl);
		if(j != bpl)
			sysfatal("unloadmemimage");
	}

	/* allocate scan lines for destination. we do y first, so need at least Dy(m->r) lines */
	bpl = bytesperline(Rect(0, 0, xsize, Dy(m->r)), m->depth);
	for(i=0; i<max(ysize, Dy(m->r)); i++){
		nscan[i] = malloc(bpl);
		if(nscan[i] == nil)
			sysfatal("can't allocate: %r");
	}

	/* resample in X */
	nchan = m->depth/8;
	for(i=0; i<Dy(m->r); i++){
		for(j=0; j<nchan; j++){
			if(j==0 && m->chan==XRGB32)
				continue;
			resamplex(oscan[i], j, nchan, Dx(m->r), nscan[i], xsize);
		}
		free(oscan[i]);
		oscan[i] = nscan[i];
		nscan[i] = malloc(bpl);
		if(nscan[i] == nil)
			sysfatal("can't allocate: %r");
	}

	/* resample in Y */
	for(i=0; i<xsize; i++)
		for(j=0; j<nchan; j++)
			resampley(oscan, nchan*i+j, Dy(m->r), nscan, ysize);

	/* pack data into destination */
	bpl = bytesperline(new->r, m->depth);
	for(i=0; i<ysize; i++){
		j = loadmemimage(new, Rect(0, i, xsize, i+1), nscan[i], bpl);
		if(j != bpl)
			sysfatal("loadmemimage: %r");
	}
	return new;
}

void
main(int argc, char *argv[])
{
	int i, fd, xsize, ysize, xpercent, ypercent;
	Rectangle rparam;
	Memimage *m, *new, *t1, *t2;
	char *file;
	ulong tchan;
	char tmp[100];
	double v;

	for(i=-K2; i<=K2; i++){
		K[K2+i] = kaiser(i/10., K2/10., 4.);
/*		print("%g %g\n", i/10., K[K2+i]); */
	}

	/* normalize */
	v = 0.0;
	for(i=0; i<NK; i++)
		v += K[i];
	for(i=0; i<NK; i++)
		K[i] /= v;

	memimageinit();
	memset(&rparam, 0, sizeof rparam);
	xsize = ysize = 0;
	xpercent = ypercent = 0;

	ARGBEGIN{
	case 'a':	/* compatibility; equivalent to just -x or -y */
		if(xsize != 0 || ysize != 0)
			usage();
		xsize = getint(ARGF(), &xpercent);
		if(xsize <= 0)
			usage();
		ysize = xsize;
		ypercent = xpercent;
		break;
	case 'x':
		if(xsize != 0)
			usage();
		xsize = getint(ARGF(), &xpercent);
		if(xsize <= 0)
			usage();
		break;
	case 'y':
		if(ysize != 0)
			usage();
		ysize = getint(ARGF(), &ypercent);
		if(ysize <= 0)
			usage();
		break;
	default:
		usage();
	}ARGEND

	if(xsize == 0 && ysize == 0)
		usage();

	file = "<stdin>";
	fd = 0;
	if(argc > 1)
		usage();
	else if(argc == 1){
		file = argv[0];
		fd = open(file, OREAD);
		if(fd < 0)
			sysfatal("can't open %s: %r", file);
	}

	m = readmemimage(fd);
	if(m == nil)
		sysfatal("can't read %s: %r", file);

	if(xpercent)
		xsize = Dx(m->r)*xsize/100;
	if(ypercent)
		ysize = Dy(m->r)*ysize/100;
	if(ysize == 0)
		ysize = (xsize * Dy(m->r)) / Dx(m->r);
	if(xsize == 0)
		xsize = (ysize * Dx(m->r)) / Dy(m->r);

	new = nil;
	switch(m->chan){

	case GREY8:
	case RGB24:
	case RGBA32:
	case ARGB32:
	case XRGB32:
		new = resample(xsize, ysize, m);
		break;

	case CMAP8:
	case RGB15:
	case RGB16:
		tchan = RGB24;
		goto Convert;

	case GREY1:
	case GREY2:
	case GREY4:
		tchan = GREY8;
	Convert:
		/* use library to convert to byte-per-chan form, then convert back */
		t1 = allocmemimage(m->r, tchan);
		if(t1 == nil)
			sysfatal("can't allocate temporary image: %r");
		memimagedraw(t1, t1->r, m, m->r.min, nil, ZP, S);
		t2 = resample(xsize, ysize, t1);
		freememimage(t1);
		new = allocmemimage(Rect(0, 0, xsize, ysize), m->chan);
		if(new == nil)
			sysfatal("can't allocate new image: %r");
		/* should do error diffusion here */
		memimagedraw(new, new->r, t2, t2->r.min, nil, ZP, S);
		freememimage(t2);
		break;

	default:
		sysfatal("can't handle channel type %s", chantostr(tmp, m->chan));
	}

	assert(new);
	if(writememimage(1, new) < 0)
		sysfatal("write error on output: %r");

	exits(nil);
}
