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

#define DBG if(0)
#define RGB2K(r,g,b)	((299*((u32int)(r))+587*((u32int)(g))+114*((u32int)(b)))/1000)

/*
 * This program tests the 'memimagedraw' primitive stochastically.
 * It tests the combination aspects of it thoroughly, but since the
 * three images it uses are disjoint, it makes no check of the
 * correct behavior when images overlap.  That is, however, much
 * easier to get right and to test.
 */

void	drawonepixel(Memimage*, Point, Memimage*, Point, Memimage*, Point);
void	verifyone(void);
void	verifyline(void);
void	verifyrect(void);
void	verifyrectrepl(int, int);
void putpixel(Memimage *img, Point pt, u32int nv);
u32int rgbatopix(uchar, uchar, uchar, uchar);

char *dchan, *schan, *mchan;
int dbpp, sbpp, mbpp;

int drawdebug=0;
int	seed;
int	niters = 100;
int	dbpp;	/* bits per pixel in destination */
int	sbpp;	/* bits per pixel in src */
int	mbpp;	/* bits per pixel in mask */
int	dpm;	/* pixel mask at high part of byte, in destination */
int	nbytes;	/* in destination */

int	Xrange	= 64;
int	Yrange	= 8;

Memimage	*dst;
Memimage	*src;
Memimage	*mask;
Memimage	*stmp;
Memimage	*mtmp;
Memimage	*ones;
uchar	*dstbits;
uchar	*srcbits;
uchar	*maskbits;
u32int	*savedstbits;

void
rdb(void)
{
}

int
iprint(char *fmt, ...)
{
	int n;	
	va_list va;
	char buf[1024];

	va_start(va, fmt);
	n = doprint(buf, buf+sizeof buf, fmt, va) - buf;
	va_end(va);

	write(1,buf,n);
	return 1;
}

void
main(int argc, char *argv[])
{
	memimageinit();
	seed = time(0);

	ARGBEGIN{
	case 'x':
		Xrange = atoi(ARGF());
		break;
	case 'y':
		Yrange = atoi(ARGF());
		break;
	case 'n':
		niters = atoi(ARGF());
		break;
	case 's':
		seed = atoi(ARGF());
		break;
	}ARGEND

	dchan = "r8g8b8";
	schan = "r8g8b8";
	mchan = "r8g8b8";
	switch(argc){
	case 3:	mchan = argv[2];
	case 2:	schan = argv[1];
	case 1:	dchan = argv[0];
	case 0:	break;
	default:	goto Usage;
	Usage:
		fprint(2, "usage: dtest [dchan [schan [mchan]]]\n");
		exits("usage");
	}

	fmtinstall('b', numbconv);	/* binary! */

	fprint(2, "%s -x %d -y %d -s 0x%x %s %s %s\n", argv0, Xrange, Yrange, seed, dchan, schan, mchan);
	srand(seed);

	dst = allocmemimage(Rect(0, 0, Xrange, Yrange), strtochan(dchan));
	src = allocmemimage(Rect(0, 0, Xrange, Yrange), strtochan(schan));
	mask = allocmemimage(Rect(0, 0, Xrange, Yrange), strtochan(mchan));
	stmp = allocmemimage(Rect(0, 0, Xrange, Yrange), strtochan(schan));
	mtmp = allocmemimage(Rect(0, 0, Xrange, Yrange), strtochan(mchan));
	ones = allocmemimage(Rect(0, 0, Xrange, Yrange), strtochan(mchan));
//	print("chan %lux %lux %lux %lux %lux %lux\n", dst->chan, src->chan, mask->chan, stmp->chan, mtmp->chan, ones->chan);
	if(dst==0 || src==0 || mask==0 || mtmp==0 || ones==0) {
	Alloc:
		fprint(2, "dtest: allocation failed: %r\n");
		exits("alloc");
	}
	nbytes = (4*Xrange+4)*Yrange;
	srcbits = malloc(nbytes);
	dstbits = malloc(nbytes);
	maskbits = malloc(nbytes);
	savedstbits = malloc(nbytes);
	if(dstbits==0 || srcbits==0 || maskbits==0 || savedstbits==0)
		goto Alloc;
	dbpp = dst->depth;
	sbpp = src->depth;
	mbpp = mask->depth;
	dpm = 0xFF ^ (0xFF>>dbpp);
	memset(ones->data->bdata, 0xFF, ones->width*sizeof(u32int)*Yrange);


	fprint(2, "dtest: verify single pixel operation\n");
	verifyone();

	fprint(2, "dtest: verify full line non-replicated\n");
	verifyline();

	fprint(2, "dtest: verify full rectangle non-replicated\n");
	verifyrect();

	fprint(2, "dtest: verify full rectangle source replicated\n");
	verifyrectrepl(1, 0);

	fprint(2, "dtest: verify full rectangle mask replicated\n");
	verifyrectrepl(0, 1);

	fprint(2, "dtest: verify full rectangle source and mask replicated\n");
	verifyrectrepl(1, 1);

	exits(0);
}

/*
 * Dump out an ASCII representation of an image.  The label specifies
 * a list of characters to put at various points in the picture.
 */
static void
Bprintr5g6b5(Biobuf *bio, char*, u32int v)
{
	int r,g,b;
	r = (v>>11)&31;
	g = (v>>5)&63;
	b = v&31;
	Bprint(bio, "%.2x%.2x%.2x", r,g,b);
}

static void
Bprintr5g5b5a1(Biobuf *bio, char*, u32int v)
{
	int r,g,b,a;
	r = (v>>11)&31;
	g = (v>>6)&31;
	b = (v>>1)&31;
	a = v&1;
	Bprint(bio, "%.2x%.2x%.2x%.2x", r,g,b,a);
}

void
dumpimage(char *name, Memimage *img, void *vdata, Point labelpt)
{
	Biobuf b;
	uchar *data;
	uchar *p;
	char *arg;
	void (*fmt)(Biobuf*, char*, u32int);
	int npr, x, y, nb, bpp;
	u32int v, mask;
	Rectangle r;

	fmt = nil;
	arg = nil;
	switch(img->depth){
	case 1:
	case 2:
	case 4:
		fmt = (void(*)(Biobuf*,char*,u32int))Bprint;
		arg = "%.1ux";
		break;
	case 8:
		fmt = (void(*)(Biobuf*,char*,u32int))Bprint;
		arg = "%.2ux";
		break;
	case 16:
		arg = nil;
		if(img->chan == RGB16)
			fmt = Bprintr5g6b5;
		else{
			fmt = (void(*)(Biobuf*,char*,u32int))Bprint;
			arg = "%.4ux";
		}
		break;
	case 24:
		fmt = (void(*)(Biobuf*,char*,u32int))Bprint;
		arg = "%.6lux";
		break;
	case 32:
		fmt = (void(*)(Biobuf*,char*,u32int))Bprint;
		arg = "%.8lux";
		break;
	}
	if(fmt == nil){
		fprint(2, "bad format\n");
		abort();
	}

	r  = img->r;
	Binit(&b, 2, OWRITE);
	data = vdata;
	bpp = img->depth;
	Bprint(&b, "%s\t%d\tr %R clipr %R repl %d data %p *%P\n", name, r.min.x, r, img->clipr, (img->flags&Frepl) ? 1 : 0, vdata, labelpt);
	mask = (1ULL<<bpp)-1;
//	for(y=r.min.y; y<r.max.y; y++){
	for(y=0; y<Yrange; y++){
		nb = 0;
		v = 0;
		p = data+(byteaddr(img, Pt(0,y))-(uchar*)img->data->bdata);
		Bprint(&b, "%-4d\t", y);
//		for(x=r.min.x; x<r.max.x; x++){
		for(x=0; x<Xrange; x++){
			if(x==0)
				Bprint(&b, "\t");

			if(x != 0 && (x%8)==0)
				Bprint(&b, " ");

			npr = 0;
			if(x==labelpt.x && y==labelpt.y){
				Bprint(&b, "*");
				npr++;
			}
			if(npr == 0)
				Bprint(&b, " ");

			while(nb < bpp){
				v &= (1<<nb)-1;
				v |= (u32int)(*p++) << nb;
				nb += 8;
			}
			nb -= bpp;
//			print("bpp %d v %.8lux mask %.8lux nb %d\n", bpp, v, mask, nb);
			fmt(&b, arg, (v>>nb)&mask);
		}
		Bprint(&b, "\n");
	}
	Bterm(&b);
}

/*
 * Verify that the destination pixel has the specified value.
 * The value is in the high bits of v, suitably masked, but must
 * be extracted from the destination Memimage.
 */
void
checkone(Point p, Point sp, Point mp)
{
	int delta;
	uchar *dp, *sdp;

	delta = (uchar*)byteaddr(dst, p)-(uchar*)dst->data->bdata;
	dp = (uchar*)dst->data->bdata+delta;
	sdp = (uchar*)savedstbits+delta;

	if(memcmp(dp, sdp, (dst->depth+7)/8) != 0) {
		fprint(2, "dtest: one bad pixel drawing at dst %P from source %P mask %P\n", p, sp, mp);
		fprint(2, " %.2ux %.2ux %.2ux %.2ux should be %.2ux %.2ux %.2ux %.2ux\n",
			dp[0], dp[1], dp[2], dp[3], sdp[0], sdp[1], sdp[2], sdp[3]);
		fprint(2, "addresses dst %p src %p mask %p\n", dp, byteaddr(src, sp), byteaddr(mask, mp));
		dumpimage("src", src, src->data->bdata, sp);
		dumpimage("mask", mask, mask->data->bdata, mp);
		dumpimage("origdst", dst, dstbits, p);
		dumpimage("dst", dst, dst->data->bdata, p);
		dumpimage("gooddst", dst, savedstbits, p);
		abort();
	}
}

/*
 * Verify that the destination line has the same value as the saved line.
 */
#define RECTPTS(r) (r).min.x, (r).min.y, (r).max.x, (r).max.y
void
checkline(Rectangle r, Point sp, Point mp, int y, Memimage *stmp, Memimage *mtmp)
{
	u32int *dp;
	int nb;
	u32int *saved;

	dp = wordaddr(dst, Pt(0, y));
	saved = savedstbits + y*dst->width;
	if(dst->depth < 8)
		nb = Xrange/(8/dst->depth);
	else
		nb = Xrange*(dst->depth/8);
	if(memcmp(dp, saved, nb) != 0){
		fprint(2, "dtest: bad line at y=%d; saved %p dp %p\n", y, saved, dp);
		fprint(2, "draw dst %R src %P mask %P\n", r, sp, mp);
		dumpimage("src", src, src->data->bdata, sp);
		if(stmp) dumpimage("stmp", stmp, stmp->data->bdata, sp);
		dumpimage("mask", mask, mask->data->bdata, mp);
		if(mtmp) dumpimage("mtmp", mtmp, mtmp->data->bdata, mp);
		dumpimage("origdst", dst, dstbits, r.min);
		dumpimage("dst", dst, dst->data->bdata, r.min);
		dumpimage("gooddst", dst, savedstbits, r.min);
		abort();
	}
}

/*
 * Fill the bits of an image with random data.
 * The Memimage parameter is used only to make sure
 * the data is well formatted: only ucbits is written.
 */
void
fill(Memimage *img, uchar *ucbits)
{
	int i, x, y;
	ushort *up;
	uchar alpha, r, g, b;
	void *data;

	if((img->flags&Falpha) == 0){
		up = (ushort*)ucbits;
		for(i=0; i<nbytes/2; i++)
			*up++ = lrand() >> 7;
		if(i+i != nbytes)
			*(uchar*)up = lrand() >> 7;
	}else{
		data = img->data->bdata;
		img->data->bdata = ucbits;

		for(x=img->r.min.x; x<img->r.max.x; x++)
		for(y=img->r.min.y; y<img->r.max.y; y++){
			alpha = rand() >> 4;
			r = rand()%(alpha+1);
			g = rand()%(alpha+1);
			b = rand()%(alpha+1);
			putpixel(img, Pt(x,y), rgbatopix(r,g,b,alpha));
		}
		img->data->bdata = data;
	}
		
}

/*
 * Mask is preset; do the rest
 */
void
verifyonemask(void)
{
	Point dp, sp, mp;

	fill(dst, dstbits);
	fill(src, srcbits);
	memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange);
	memmove(src->data->bdata, srcbits, src->width*sizeof(u32int)*Yrange);
	memmove(mask->data->bdata, maskbits, mask->width*sizeof(u32int)*Yrange);

	dp.x = nrand(Xrange);
	dp.y = nrand(Yrange);

	sp.x = nrand(Xrange);
	sp.y = nrand(Yrange);

	mp.x = nrand(Xrange);
	mp.y = nrand(Yrange);

	drawonepixel(dst, dp, src, sp, mask, mp);
	memmove(mask->data->bdata, maskbits, mask->width*sizeof(u32int)*Yrange);
	memmove(savedstbits, dst->data->bdata, dst->width*sizeof(u32int)*Yrange);
	
	memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange);
	memimagedraw(dst, Rect(dp.x, dp.y, dp.x+1, dp.y+1), src, sp, mask, mp, SoverD);
	memmove(mask->data->bdata, maskbits, mask->width*sizeof(u32int)*Yrange);

	checkone(dp, sp, mp);
}

void
verifyone(void)
{
	int i;

	/* mask all zeros */
	memset(maskbits, 0, nbytes);
	for(i=0; i<niters; i++)
		verifyonemask();

	/* mask all ones */
	memset(maskbits, 0xFF, nbytes);
	for(i=0; i<niters; i++)
		verifyonemask();

	/* random mask */
	for(i=0; i<niters; i++){
		fill(mask, maskbits);
		verifyonemask();
	}
}

/*
 * Mask is preset; do the rest
 */
void
verifylinemask(void)
{
	Point sp, mp, tp, up;
	Rectangle dr;
	int x;

	fill(dst, dstbits);
	fill(src, srcbits);
	memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange);
	memmove(src->data->bdata, srcbits, src->width*sizeof(u32int)*Yrange);
	memmove(mask->data->bdata, maskbits, mask->width*sizeof(u32int)*Yrange);

	dr.min.x = nrand(Xrange-1);
	dr.min.y = nrand(Yrange-1);
	dr.max.x = dr.min.x + 1 + nrand(Xrange-1-dr.min.x);
	dr.max.y = dr.min.y + 1;

	sp.x = nrand(Xrange);
	sp.y = nrand(Yrange);

	mp.x = nrand(Xrange);
	mp.y = nrand(Yrange);

	tp = sp;
	up = mp;
	for(x=dr.min.x; x<dr.max.x && tp.x<Xrange && up.x<Xrange; x++,tp.x++,up.x++)
		memimagedraw(dst, Rect(x, dr.min.y, x+1, dr.min.y+1), src, tp, mask, up, SoverD);
	memmove(savedstbits, dst->data->bdata, dst->width*sizeof(u32int)*Yrange);

	memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange);

	memimagedraw(dst, dr, src, sp, mask, mp, SoverD);
	checkline(dr, drawrepl(src->r, sp), drawrepl(mask->r, mp), dr.min.y, nil, nil);
}

void
verifyline(void)
{
	int i;

	/* mask all ones */
	memset(maskbits, 0xFF, nbytes);
	for(i=0; i<niters; i++)
		verifylinemask();

	/* mask all zeros */
	memset(maskbits, 0, nbytes);
	for(i=0; i<niters; i++)
		verifylinemask();

	/* random mask */
	for(i=0; i<niters; i++){
		fill(mask, maskbits);
		verifylinemask();
	}
}

/*
 * Mask is preset; do the rest
 */
void
verifyrectmask(void)
{
	Point sp, mp, tp, up;
	Rectangle dr;
	int x, y;

	fill(dst, dstbits);
	fill(src, srcbits);
	memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange);
	memmove(src->data->bdata, srcbits, src->width*sizeof(u32int)*Yrange);
	memmove(mask->data->bdata, maskbits, mask->width*sizeof(u32int)*Yrange);

	dr.min.x = nrand(Xrange-1);
	dr.min.y = nrand(Yrange-1);
	dr.max.x = dr.min.x + 1 + nrand(Xrange-1-dr.min.x);
	dr.max.y = dr.min.y + 1 + nrand(Yrange-1-dr.min.y);

	sp.x = nrand(Xrange);
	sp.y = nrand(Yrange);

	mp.x = nrand(Xrange);
	mp.y = nrand(Yrange);

	tp = sp;
	up = mp;
	for(y=dr.min.y; y<dr.max.y && tp.y<Yrange && up.y<Yrange; y++,tp.y++,up.y++){
		for(x=dr.min.x; x<dr.max.x && tp.x<Xrange && up.x<Xrange; x++,tp.x++,up.x++)
			memimagedraw(dst, Rect(x, y, x+1, y+1), src, tp, mask, up, SoverD);
		tp.x = sp.x;
		up.x = mp.x;
	}
	memmove(savedstbits, dst->data->bdata, dst->width*sizeof(u32int)*Yrange);

	memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange);

	memimagedraw(dst, dr, src, sp, mask, mp, SoverD);
	for(y=0; y<Yrange; y++)
		checkline(dr, drawrepl(src->r, sp), drawrepl(mask->r, mp), y, nil, nil);
}

void
verifyrect(void)
{
	int i;

	/* mask all zeros */
	memset(maskbits, 0, nbytes);
	for(i=0; i<niters; i++)
		verifyrectmask();

	/* mask all ones */
	memset(maskbits, 0xFF, nbytes);
	for(i=0; i<niters; i++)
		verifyrectmask();

	/* random mask */
	for(i=0; i<niters; i++){
		fill(mask, maskbits);
		verifyrectmask();
	}
}

Rectangle
randrect(void)
{
	Rectangle r;

	r.min.x = nrand(Xrange-1);
	r.min.y = nrand(Yrange-1);
	r.max.x = r.min.x + 1 + nrand(Xrange-1-r.min.x);
	r.max.y = r.min.y + 1 + nrand(Yrange-1-r.min.y);
	return r;
}

/*
 * Return coordinate corresponding to x withing range [minx, maxx)
 */
int
tilexy(int minx, int maxx, int x)
{
	int sx;

	sx = (x-minx) % (maxx-minx);
	if(sx < 0)
		sx += maxx-minx;
	return sx+minx;
}

void
replicate(Memimage *i, Memimage *tmp)
{
	Rectangle r, r1;
	int x, y, nb;

	/* choose the replication window (i->r) */
	r.min.x = nrand(Xrange-1);
	r.min.y = nrand(Yrange-1);
	/* make it trivial more often than pure chance allows */
	switch(lrand()&0){
	case 1:
		r.max.x = r.min.x + 2;
		r.max.y = r.min.y + 2;
		if(r.max.x < Xrange && r.max.y < Yrange)
			break;
		/* fall through */
	case 0:
		r.max.x = r.min.x + 1;
		r.max.y = r.min.y + 1;
		break;
	default:
		if(r.min.x+3 >= Xrange)
			r.max.x = Xrange;
		else
			r.max.x = r.min.x+3 + nrand(Xrange-(r.min.x+3));

		if(r.min.y+3 >= Yrange)
			r.max.y = Yrange;
		else
			r.max.y = r.min.y+3 + nrand(Yrange-(r.min.y+3));
	}
	assert(r.min.x >= 0);	
	assert(r.max.x <= Xrange);
	assert(r.min.y >= 0);
	assert(r.max.y <= Yrange);
	/* copy from i to tmp so we have just the replicated bits */
	nb = tmp->width*sizeof(u32int)*Yrange;
	memset(tmp->data->bdata, 0, nb);
	memimagedraw(tmp, r, i, r.min, ones, r.min, SoverD);
	memmove(i->data->bdata, tmp->data->bdata, nb);
	/* i is now a non-replicated instance of the replication */
	/* replicate it by hand through tmp */
	memset(tmp->data->bdata, 0, nb);
	x = -(tilexy(r.min.x, r.max.x, 0)-r.min.x);
	for(; x<Xrange; x+=Dx(r)){
		y = -(tilexy(r.min.y, r.max.y, 0)-r.min.y);
		for(; y<Yrange; y+=Dy(r)){
			/* set r1 to instance of tile by translation */
			r1.min.x = x;
			r1.min.y = y;
			r1.max.x = r1.min.x+Dx(r);
			r1.max.y = r1.min.y+Dy(r);
			memimagedraw(tmp, r1, i, r.min, ones, r.min, SoverD);
		}
	}
	i->flags |= Frepl;
	i->r = r;
	i->clipr = randrect();
//	fprint(2, "replicate [[%d %d] [%d %d]] [[%d %d][%d %d]]\n", r.min.x, r.min.y, r.max.x, r.max.y,
//		i->clipr.min.x, i->clipr.min.y, i->clipr.max.x, i->clipr.max.y);
	tmp->clipr = i->clipr;
}

/*
 * Mask is preset; do the rest
 */
void
verifyrectmaskrepl(int srcrepl, int maskrepl)
{
	Point sp, mp, tp, up;
	Rectangle dr;
	int x, y;
	Memimage *s, *m;

//	print("verfrect %d %d\n", srcrepl, maskrepl);
	src->flags &= ~Frepl;
	src->r = Rect(0, 0, Xrange, Yrange);
	src->clipr = src->r;
	stmp->flags &= ~Frepl;
	stmp->r = Rect(0, 0, Xrange, Yrange);
	stmp->clipr = src->r;
	mask->flags &= ~Frepl;
	mask->r = Rect(0, 0, Xrange, Yrange);
	mask->clipr = mask->r;
	mtmp->flags &= ~Frepl;
	mtmp->r = Rect(0, 0, Xrange, Yrange);
	mtmp->clipr = mask->r;

	fill(dst, dstbits);
	fill(src, srcbits);

	memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange);
	memmove(src->data->bdata, srcbits, src->width*sizeof(u32int)*Yrange);
	memmove(mask->data->bdata, maskbits, mask->width*sizeof(u32int)*Yrange);

	if(srcrepl){
		replicate(src, stmp);
		s = stmp;
	}else
		s = src;
	if(maskrepl){
		replicate(mask, mtmp);
		m = mtmp;
	}else
		m = mask;

	dr = randrect();

	sp.x = nrand(Xrange);
	sp.y = nrand(Yrange);

	mp.x = nrand(Xrange);
	mp.y = nrand(Yrange);

DBG	print("smalldraws\n");
	for(tp.y=sp.y,up.y=mp.y,y=dr.min.y; y<dr.max.y && tp.y<Yrange && up.y<Yrange; y++,tp.y++,up.y++)
		for(tp.x=sp.x,up.x=mp.x,x=dr.min.x; x<dr.max.x && tp.x<Xrange && up.x<Xrange; x++,tp.x++,up.x++)
			memimagedraw(dst, Rect(x, y, x+1, y+1), s, tp, m, up, SoverD);
	memmove(savedstbits, dst->data->bdata, dst->width*sizeof(u32int)*Yrange);

	memmove(dst->data->bdata, dstbits, dst->width*sizeof(u32int)*Yrange);

DBG	print("bigdraw\n");
	memimagedraw(dst, dr, src, sp, mask, mp, SoverD);
	for(y=0; y<Yrange; y++)
		checkline(dr, drawrepl(src->r, sp), drawrepl(mask->r, mp), y, srcrepl?stmp:nil, maskrepl?mtmp:nil);
}

void
verifyrectrepl(int srcrepl, int maskrepl)
{
	int i;

	/* mask all ones */
	memset(maskbits, 0xFF, nbytes);
	for(i=0; i<niters; i++)
		verifyrectmaskrepl(srcrepl, maskrepl);

	/* mask all zeros */
	memset(maskbits, 0, nbytes);
	for(i=0; i<niters; i++)
		verifyrectmaskrepl(srcrepl, maskrepl);

	/* random mask */
	for(i=0; i<niters; i++){
		fill(mask, maskbits);
		verifyrectmaskrepl(srcrepl, maskrepl);
	}
}

/*
 * Trivial draw implementation.
 * Color values are passed around as u32ints containing ααRRGGBB
 */

/*
 * Convert v, which is nhave bits wide, into its nwant bits wide equivalent.
 * Replicates to widen the value, truncates to narrow it.
 */
u32int
replbits(u32int v, int nhave, int nwant)
{
	v &= (1<<nhave)-1;
	for(; nhave<nwant; nhave*=2)
		v |= v<<nhave;
	v >>= (nhave-nwant);
	return v & ((1<<nwant)-1);
}

/*
 * Decode a pixel into the uchar* values.
 */
void
pixtorgba(u32int v, uchar *r, uchar *g, uchar *b, uchar *a)
{
	*a = v>>24;
	*r = v>>16;
	*g = v>>8;
	*b = v;
}

/*
 * Convert uchar channels into u32int pixel.
 */
u32int
rgbatopix(uchar r, uchar g, uchar b, uchar a)
{
	return (a<<24)|(r<<16)|(g<<8)|b;
}

/*
 * Retrieve the pixel value at pt in the image.
 */
u32int
getpixel(Memimage *img, Point pt)
{
	uchar r, g, b, a, *p;
	int nbits, npack, bpp;
	u32int v, c, rbits, bits;

	r = g = b = 0;
	a = ~0;	/* default alpha is full */

	p = byteaddr(img, pt);
	v = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24);
	bpp = img->depth;
	if(bpp<8){
		/*
		 * Sub-byte greyscale pixels.
		 *
		 * We want to throw away the top pt.x%npack pixels and then use the next bpp bits
		 * in the bottom byte of v.  This madness is due to having big endian bits
		 * but little endian bytes.
		 */
		npack = 8/bpp;
		v >>= 8 - bpp*(pt.x%npack+1);
		v &= (1<<bpp)-1;
		r = g = b = replbits(v, bpp, 8);
	}else{
		/*
		 * General case.  We need to parse the channel descriptor and do what it says.
		 * In all channels but the color map, we replicate to 8 bits because that's the
		 * precision that all calculations are done at.
		 *
		 * In the case of the color map, we leave the bits alone, in case a color map
		 * with less than 8 bits of index is used.  This is currently disallowed, so it's
		 * sort of silly.
		 */

		for(c=img->chan; c; c>>=8){
			nbits = NBITS(c);
			bits = v & ((1<<nbits)-1);
			rbits = replbits(bits, nbits, 8);
			v >>= nbits;
			switch(TYPE(c)){
			case CRed:
				r = rbits;
				break;
			case CGreen:
				g = rbits;
				break;
			case CBlue:
				b = rbits;
				break;
			case CGrey:
				r = g = b = rbits;
				break;
			case CAlpha:
				a = rbits;
				break;
			case CMap:
				p = img->cmap->cmap2rgb + 3*bits;
				r = p[0];
				g = p[1];
				b = p[2];
				break;
			case CIgnore:
				break;
			default:
				fprint(2, "unknown channel type %lud\n", TYPE(c));
				abort();
			}
		}
	}
	return rgbatopix(r, g, b, a);
}

/*
 * Return the greyscale equivalent of a pixel.
 */
uchar
getgrey(Memimage *img, Point pt)
{
	uchar r, g, b, a;
	pixtorgba(getpixel(img, pt), &r, &g, &b, &a);
	return RGB2K(r, g, b);
}

/*
 * Return the value at pt in image, if image is interpreted
 * as a mask.  This means the alpha channel if present, else
 * the greyscale or its computed equivalent.
 */
uchar
getmask(Memimage *img, Point pt)
{
	if(img->flags&Falpha)
		return getpixel(img, pt)>>24;
	else
		return getgrey(img, pt);
}
#undef DBG

#define DBG if(0)
/*
 * Write a pixel to img at point pt.
 * 
 * We do this by reading a 32-bit little endian
 * value from p and then writing it back
 * after tweaking the appropriate bits.  Because
 * the data is little endian, we don't have to worry
 * about what the actual depth is, as long as it is
 * less than 32 bits.
 */
void
putpixel(Memimage *img, Point pt, u32int nv)
{
	uchar r, g, b, a, *p, *q;
	u32int c, mask, bits, v;
	int bpp, sh, npack, nbits;

	pixtorgba(nv, &r, &g, &b, &a);

	p = byteaddr(img, pt);
	v = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24);
	bpp = img->depth;
DBG print("v %.8lux...", v);
	if(bpp < 8){
		/*
		 * Sub-byte greyscale pixels.  We need to skip the leftmost pt.x%npack pixels,
		 * which is equivalent to skipping the rightmost npack - pt.x%npack - 1 pixels.
		 */	
		npack = 8/bpp;
		sh = bpp*(npack - pt.x%npack - 1);
		bits = RGB2K(r,g,b);
DBG print("repl %lux 8 %d = %lux...", bits, bpp, replbits(bits, 8, bpp));
		bits = replbits(bits, 8, bpp);
		mask = (1<<bpp)-1;
DBG print("bits %lux mask %lux sh %d...", bits, mask, sh);
		mask <<= sh;
		bits <<= sh;
DBG print("(%lux & %lux) | (%lux & %lux)", v, ~mask, bits, mask);
		v = (v & ~mask) | (bits & mask);
	} else {
		/*
		 * General case.  We need to parse the channel descriptor again.
		 */
		sh = 0;
		for(c=img->chan; c; c>>=8){
			nbits = NBITS(c);
			switch(TYPE(c)){
			case CRed:
				bits = r;
				break;
			case CGreen:
				bits = g;
				break;
			case CBlue:
				bits = b;
				break;
			case CGrey:
				bits = RGB2K(r, g, b);
				break;
			case CAlpha:
				bits = a;
				break;
			case CIgnore:
				bits = 0;
				break;
			case CMap:
				q = img->cmap->rgb2cmap;
				bits = q[(r>>4)*16*16+(g>>4)*16+(b>>4)];
				break;
			default:
				SET(bits);
				fprint(2, "unknown channel type %lud\n", TYPE(c));
				abort();
			}

DBG print("repl %lux 8 %d = %lux...", bits, nbits, replbits(bits, 8, nbits));
			if(TYPE(c) != CMap)
				bits = replbits(bits, 8, nbits);
			mask = (1<<nbits)-1;
DBG print("bits %lux mask %lux sh %d...", bits, mask, sh);
			bits <<= sh;
			mask <<= sh;
			v = (v & ~mask) | (bits & mask);
			sh += nbits;
		}
	}
DBG print("v %.8lux\n", v);
	p[0] = v;
	p[1] = v>>8;
	p[2] = v>>16;
	p[3] = v>>24;	
}
#undef DBG

#define DBG if(0)
void
drawonepixel(Memimage *dst, Point dp, Memimage *src, Point sp, Memimage *mask, Point mp)
{
	uchar m, M, sr, sg, sb, sa, sk, dr, dg, db, da, dk;

	pixtorgba(getpixel(dst, dp), &dr, &dg, &db, &da);
	pixtorgba(getpixel(src, sp), &sr, &sg, &sb, &sa);
	m = getmask(mask, mp);
	M = 255-(sa*m)/255;

DBG print("dst %x %x %x %x src %x %x %x %x m %x = ", dr,dg,db,da, sr,sg,sb,sa, m);
	if(dst->flags&Fgrey){
		/*
		 * We need to do the conversion to grey before the alpha calculation
		 * because the draw operator does this, and we need to be operating
		 * at the same precision so we get exactly the same answers.
		 */
		sk = RGB2K(sr, sg, sb);
		dk = RGB2K(dr, dg, db);
		dk = (sk*m + dk*M)/255;
		dr = dg = db = dk;
		da = (sa*m + da*M)/255;
	}else{
		/*
		 * True color alpha calculation treats all channels (including alpha)
		 * the same.  It might have been nice to use an array, but oh well.
		 */
		dr = (sr*m + dr*M)/255;
		dg = (sg*m + dg*M)/255;
		db = (sb*m + db*M)/255;
		da = (sa*m + da*M)/255;
	}

DBG print("%x %x %x %x\n", dr,dg,db,da);
	putpixel(dst, dp, rgbatopix(dr, dg, db, da));
}
