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

int drawdebug;
static int	tablesbuilt;

/* perfect approximation to NTSC = .299r+.587g+.114b when 0 ≤ r,g,b < 256 */
#define RGB2K(r,g,b)	((156763*(r)+307758*(g)+59769*(b))>>19)

/*
 * For 16-bit values, x / 255 == (t = x+1, (t+(t>>8)) >> 8).
 * We add another 127 to round to the nearest value rather
 * than truncate.
 *
 * CALCxy does x bytewise calculations on y input images (x=1,4; y=1,2).
 * CALC2x does two parallel 16-bit calculations on y input images (y=1,2).
 */
#define CALC11(a, v, tmp) \
	(tmp=(a)*(v)+128, (tmp+(tmp>>8))>>8)

#define CALC12(a1, v1, a2, v2, tmp) \
	(tmp=(a1)*(v1)+(a2)*(v2)+128, (tmp+(tmp>>8))>>8)

#define MASK 0xFF00FF

#define CALC21(a, vvuu, tmp) \
	(tmp=(a)*(vvuu)+0x00800080, ((tmp+((tmp>>8)&MASK))>>8)&MASK)

#define CALC41(a, rgba, tmp1, tmp2) \
	(CALC21(a, rgba & MASK, tmp1) | \
	 (CALC21(a, (rgba>>8)&MASK, tmp2)<<8))

#define CALC22(a1, vvuu1, a2, vvuu2, tmp) \
	(tmp=(a1)*(vvuu1)+(a2)*(vvuu2)+0x00800080, ((tmp+((tmp>>8)&MASK))>>8)&MASK)

#define CALC42(a1, rgba1, a2, rgba2, tmp1, tmp2) \
	(CALC22(a1, rgba1 & MASK, a2, rgba2 & MASK, tmp1) | \
	 (CALC22(a1, (rgba1>>8) & MASK, a2, (rgba2>>8) & MASK, tmp2)<<8))

static void mktables(void);
typedef int Subdraw(Memdrawparam*);
static Subdraw chardraw, alphadraw, memoptdraw;

static Memimage*	memones;
static Memimage*	memzeros;
Memimage *memwhite;
Memimage *memblack;
Memimage *memtransparent;
Memimage *memopaque;

int	__ifmt(Fmt*);

void
memimageinit(void)
{
	static int didinit = 0;

	if(didinit)
		return;

	didinit = 1;

	mktables();
	_memmkcmap();

	fmtinstall('R', Rfmt); 
	fmtinstall('P', Pfmt);
	fmtinstall('b', __ifmt);

	memones = allocmemimage(Rect(0,0,1,1), GREY1);
	memones->flags |= Frepl;
	memones->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
	*byteaddr(memones, ZP) = ~0;

	memzeros = allocmemimage(Rect(0,0,1,1), GREY1);
	memzeros->flags |= Frepl;
	memzeros->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
	*byteaddr(memzeros, ZP) = 0;

	if(memones == nil || memzeros == nil)
		assert(0 /*cannot initialize memimage library */);	/* RSC BUG */

	memwhite = memones;
	memblack = memzeros;
	memopaque = memones;
	memtransparent = memzeros;
}

u32int _imgtorgba(Memimage*, u32int);
u32int _rgbatoimg(Memimage*, u32int);
u32int _pixelbits(Memimage*, Point);

#define DBG if(drawdebug)
static Memdrawparam par;

Memdrawparam*
_memimagedrawsetup(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Point p1, int op)
{
	if(mask == nil)
		mask = memopaque;

DBG	print("memimagedraw %p/%luX %R @ %p %p/%luX %P %p/%luX %P... ", dst, dst->chan, r, dst->data->bdata, src, src->chan, p0, mask, mask->chan, p1);

	if(drawclip(dst, &r, src, &p0, mask, &p1, &par.sr, &par.mr) == 0){
/*		if(drawdebug) */
/*			iprint("empty clipped rectangle\n"); */
		return nil;
	}

	if(op < Clear || op > SoverD){
/*		if(drawdebug) */
/*			iprint("op out of range: %d\n", op); */
		return nil;
	}

	par.op = op;
	par.dst = dst;
	par.r = r;
	par.src = src;
	/* par.sr set by drawclip */
	par.mask = mask;
	/* par.mr set by drawclip */

	par.state = 0;
	if(src->flags&Frepl){
		par.state |= Replsrc;
		if(Dx(src->r)==1 && Dy(src->r)==1){
			par.sval = pixelbits(src, src->r.min);
			par.state |= Simplesrc;
			par.srgba = _imgtorgba(src, par.sval);
			par.sdval = _rgbatoimg(dst, par.srgba);
			if((par.srgba&0xFF) == 0 && (op&DoutS)){
/*				if (drawdebug) iprint("fill with transparent source\n"); */
				return nil;	/* no-op successfully handled */
			}
			if((par.srgba&0xFF) == 0xFF)
				par.state |= Fullsrc;
		}
	}

	if(mask->flags & Frepl){
		par.state |= Replmask;
		if(Dx(mask->r)==1 && Dy(mask->r)==1){
			par.mval = pixelbits(mask, mask->r.min);
			if(par.mval == 0 && (op&DoutS)){
/*				if(drawdebug) iprint("fill with zero mask\n"); */
				return nil;	/* no-op successfully handled */
			}
			par.state |= Simplemask;
			if(par.mval == ~0)
				par.state |= Fullmask;
			par.mrgba = _imgtorgba(mask, par.mval);
		}
	}

/*	if(drawdebug) */
/*		iprint("dr %R sr %R mr %R...", r, par.sr, par.mr); */
DBG print("draw dr %R sr %R mr %R %lux\n", r, par.sr, par.mr, par.state);

	return &par;
}

void
_memimagedraw(Memdrawparam *par)
{
	/*
	 * Now that we've clipped the parameters down to be consistent, we 
	 * simply try sub-drawing routines in order until we find one that was able
	 * to handle us.  If the sub-drawing routine returns zero, it means it was
	 * unable to satisfy the request, so we do not return.
	 */

	/*
	 * Hardware support.  Each video driver provides this function,
	 * which checks to see if there is anything it can help with.
	 * There could be an if around this checking to see if dst is in video memory.
	 */
DBG print("test hwdraw\n");
	if(hwdraw(par)){
/*if(drawdebug) iprint("hw handled\n"); */
DBG print("hwdraw handled\n");
		return;
	}
	/*
	 * Optimizations using memmove and memset.
	 */
DBG print("test memoptdraw\n");
	if(memoptdraw(par)){
/*if(drawdebug) iprint("memopt handled\n"); */
DBG print("memopt handled\n");
		return;
	}

	/*
	 * Character drawing.
	 * Solid source color being painted through a boolean mask onto a high res image.
	 */
DBG print("test chardraw\n");
	if(chardraw(par)){
/*if(drawdebug) iprint("chardraw handled\n"); */
DBG print("chardraw handled\n");
		return;
	}

	/*
	 * General calculation-laden case that does alpha for each pixel.
	 */
DBG print("do alphadraw\n");
	alphadraw(par);
/*if(drawdebug) iprint("alphadraw handled\n"); */
DBG print("alphadraw handled\n");
}
#undef DBG

/*
 * Clip the destination rectangle further based on the properties of the 
 * source and mask rectangles.  Once the destination rectangle is properly
 * clipped, adjust the source and mask rectangles to be the same size.
 * Then if source or mask is replicated, move its clipped rectangle
 * so that its minimum point falls within the repl rectangle.
 *
 * Return zero if the final rectangle is null.
 */
int
drawclip(Memimage *dst, Rectangle *r, Memimage *src, Point *p0, Memimage *mask, Point *p1, Rectangle *sr, Rectangle *mr)
{
	Point rmin, delta;
	int splitcoords;
	Rectangle omr;

	if(r->min.x>=r->max.x || r->min.y>=r->max.y)
		return 0;
	splitcoords = (p0->x!=p1->x) || (p0->y!=p1->y);
	/* clip to destination */
	rmin = r->min;
	if(!rectclip(r, dst->r) || !rectclip(r, dst->clipr))
		return 0;
	/* move mask point */
	p1->x += r->min.x-rmin.x;
	p1->y += r->min.y-rmin.y;
	/* move source point */
	p0->x += r->min.x-rmin.x;
	p0->y += r->min.y-rmin.y;
	/* map destination rectangle into source */
	sr->min = *p0;
	sr->max.x = p0->x+Dx(*r);
	sr->max.y = p0->y+Dy(*r);
	/* sr is r in source coordinates; clip to source */
	if(!(src->flags&Frepl) && !rectclip(sr, src->r))
		return 0;
	if(!rectclip(sr, src->clipr))
		return 0;
	/* compute and clip rectangle in mask */
	if(splitcoords){
		/* move mask point with source */
		p1->x += sr->min.x-p0->x;
		p1->y += sr->min.y-p0->y;
		mr->min = *p1;
		mr->max.x = p1->x+Dx(*sr);
		mr->max.y = p1->y+Dy(*sr);
		omr = *mr;
		/* mr is now rectangle in mask; clip it */
		if(!(mask->flags&Frepl) && !rectclip(mr, mask->r))
			return 0;
		if(!rectclip(mr, mask->clipr))
			return 0;
		/* reflect any clips back to source */
		sr->min.x += mr->min.x-omr.min.x;
		sr->min.y += mr->min.y-omr.min.y;
		sr->max.x += mr->max.x-omr.max.x;
		sr->max.y += mr->max.y-omr.max.y;
		*p1 = mr->min;
	}else{
		if(!(mask->flags&Frepl) && !rectclip(sr, mask->r))
			return 0;
		if(!rectclip(sr, mask->clipr))
			return 0;
		*p1 = sr->min;
	}

	/* move source clipping back to destination */
	delta.x = r->min.x - p0->x;
	delta.y = r->min.y - p0->y;
	r->min.x = sr->min.x + delta.x;
	r->min.y = sr->min.y + delta.y;
	r->max.x = sr->max.x + delta.x;
	r->max.y = sr->max.y + delta.y;

	/* move source rectangle so sr->min is in src->r */
	if(src->flags&Frepl) {
		delta.x = drawreplxy(src->r.min.x, src->r.max.x, sr->min.x) - sr->min.x;
		delta.y = drawreplxy(src->r.min.y, src->r.max.y, sr->min.y) - sr->min.y;
		sr->min.x += delta.x;
		sr->min.y += delta.y;
		sr->max.x += delta.x;
		sr->max.y += delta.y;
	}
	*p0 = sr->min;

	/* move mask point so it is in mask->r */
	*p1 = drawrepl(mask->r, *p1);
	mr->min = *p1;
	mr->max.x = p1->x+Dx(*sr);
	mr->max.y = p1->y+Dy(*sr);

	assert(Dx(*sr) == Dx(*mr) && Dx(*mr) == Dx(*r));
	assert(Dy(*sr) == Dy(*mr) && Dy(*mr) == Dy(*r));
	assert(ptinrect(*p0, src->r));
	assert(ptinrect(*p1, mask->r));
	assert(ptinrect(r->min, dst->r));

	return 1;
}

/*
 * Conversion tables.
 */
static uchar replbit[1+8][256];		/* replbit[x][y] is the replication of the x-bit quantity y to 8-bit depth */
static uchar conv18[256][8];		/* conv18[x][y] is the yth pixel in the depth-1 pixel x */
static uchar conv28[256][4];		/* ... */
static uchar conv48[256][2];

/*
 * bitmap of how to replicate n bits to fill 8, for 1 ≤ n ≤ 8.
 * the X's are where to put the bottom (ones) bit of the n-bit pattern.
 * only the top 8 bits of the result are actually used.
 * (the lower 8 bits are needed to get bits in the right place
 * when n is not a divisor of 8.)
 *
 * Should check to see if its easier to just refer to replmul than
 * use the precomputed values in replbit.  On PCs it may well
 * be; on machines with slow multiply instructions it probably isn't.
 */
#define a ((((((((((((((((0
#define X *2+1)
#define _ *2)
static int replmul[1+8] = {
	0,
	a X X X X X X X X X X X X X X X X,
	a _ X _ X _ X _ X _ X _ X _ X _ X,
	a _ _ X _ _ X _ _ X _ _ X _ _ X _,
	a _ _ _ X _ _ _ X _ _ _ X _ _ _ X,
	a _ _ _ _ X _ _ _ _ X _ _ _ _ X _,
	a _ _ _ _ _ X _ _ _ _ _ X _ _ _ _, 
	a _ _ _ _ _ _ X _ _ _ _ _ _ X _ _,
	a _ _ _ _ _ _ _ X _ _ _ _ _ _ _ X,
};
#undef a
#undef X
#undef _

static void
mktables(void)
{
	int i, j, mask, sh, small;
		
	if(tablesbuilt)
		return;

	fmtinstall('R', Rfmt);
	fmtinstall('P', Pfmt);
	tablesbuilt = 1;

	/* bit replication up to 8 bits */
	for(i=0; i<256; i++){
		for(j=0; j<=8; j++){	/* j <= 8 [sic] */
			small = i & ((1<<j)-1);
			replbit[j][i] = (small*replmul[j])>>8;
		}
	}

	/* bit unpacking up to 8 bits, only powers of 2 */
	for(i=0; i<256; i++){
		for(j=0, sh=7, mask=1; j<8; j++, sh--)
			conv18[i][j] = replbit[1][(i>>sh)&mask];

		for(j=0, sh=6, mask=3; j<4; j++, sh-=2)
			conv28[i][j] = replbit[2][(i>>sh)&mask];

		for(j=0, sh=4, mask=15; j<2; j++, sh-=4)
			conv48[i][j] = replbit[4][(i>>sh)&mask];
	}
}

static uchar ones = 0xff;

/*
 * General alpha drawing case.  Can handle anything.
 */
typedef struct	Buffer	Buffer;
struct Buffer {
	/* used by most routines */
	uchar	*red;
	uchar	*grn;
	uchar	*blu;
	uchar	*alpha;
	uchar	*grey;
	u32int	*rgba;
	int	delta;	/* number of bytes to add to pointer to get next pixel to the right */

	/* used by boolcalc* for mask data */
	uchar	*m;		/* ptr to mask data r.min byte; like p->bytermin */
	int		mskip;	/* no. of left bits to skip in *m */
	uchar	*bm;		/* ptr to mask data img->r.min byte; like p->bytey0s */
	int		bmskip;	/* no. of left bits to skip in *bm */
	uchar	*em;		/* ptr to mask data img->r.max.x byte; like p->bytey0e */
	int		emskip;	/* no. of right bits to skip in *em */
};

typedef struct	Param	Param;
typedef Buffer	Readfn(Param*, uchar*, int);
typedef void	Writefn(Param*, uchar*, Buffer);
typedef Buffer	Calcfn(Buffer, Buffer, Buffer, int, int, int);

enum {
	MAXBCACHE = 16
};

/* giant rathole to customize functions with */
struct Param {
	Readfn	*replcall;
	Readfn	*greymaskcall;	
	Readfn	*convreadcall;
	Writefn	*convwritecall;

	Memimage *img;
	Rectangle	r;
	int	dx;	/* of r */
	int	needbuf;
	int	convgrey;
	int	alphaonly;

	uchar	*bytey0s;		/* byteaddr(Pt(img->r.min.x, img->r.min.y)) */
	uchar	*bytermin;	/* byteaddr(Pt(r.min.x, img->r.min.y)) */
	uchar	*bytey0e;		/* byteaddr(Pt(img->r.max.x, img->r.min.y)) */
	int		bwidth;

	int	replcache;	/* if set, cache buffers */
	Buffer	bcache[MAXBCACHE];
	u32int	bfilled;
	uchar	*bufbase;
	int	bufoff;
	int	bufdelta;

	int	dir;

	int	convbufoff;
	uchar	*convbuf;
	Param	*convdpar;
	int	convdx;
};

static uchar *drawbuf;
static int	ndrawbuf;
static int	mdrawbuf;
static Param spar, mpar, dpar;	/* easier on the stacks */
static Readfn	greymaskread, replread, readptr;
static Writefn	nullwrite;
static Calcfn	alphacalc0, alphacalc14, alphacalc2810, alphacalc3679, alphacalc5, alphacalc11, alphacalcS;
static Calcfn	boolcalc14, boolcalc236789, boolcalc1011;

static Readfn*	readfn(Memimage*);
static Readfn*	readalphafn(Memimage*);
static Writefn*	writefn(Memimage*);

static Calcfn*	boolcopyfn(Memimage*, Memimage*);
static Readfn*	convfn(Memimage*, Param*, Memimage*, Param*);

static Calcfn *alphacalc[Ncomp] = 
{
	alphacalc0,		/* Clear */
	alphacalc14,		/* DoutS */
	alphacalc2810,		/* SoutD */
	alphacalc3679,		/* DxorS */
	alphacalc14,		/* DinS */
	alphacalc5,		/* D */
	alphacalc3679,		/* DatopS */
	alphacalc3679,		/* DoverS */
	alphacalc2810,		/* SinD */
	alphacalc3679,		/* SatopD */
	alphacalc2810,		/* S */
	alphacalc11,		/* SoverD */
};

static Calcfn *boolcalc[Ncomp] =
{
	alphacalc0,		/* Clear */
	boolcalc14,		/* DoutS */
	boolcalc236789,		/* SoutD */
	boolcalc236789,		/* DxorS */
	boolcalc14,		/* DinS */
	alphacalc5,		/* D */
	boolcalc236789,		/* DatopS */
	boolcalc236789,		/* DoverS */
	boolcalc236789,		/* SinD */
	boolcalc236789,		/* SatopD */
	boolcalc1011,		/* S */
	boolcalc1011,		/* SoverD */
};

static int
allocdrawbuf(void)
{
	uchar *p;

	if(ndrawbuf > mdrawbuf){
		p = realloc(drawbuf, ndrawbuf);
		if(p == nil){
			werrstr("memimagedraw out of memory");
			return -1;
		}
		drawbuf = p;
		mdrawbuf = ndrawbuf;
	}
	return 0;
}

static void
getparam(Param *p, Memimage *img, Rectangle r, int convgrey, int needbuf)
{
	int nbuf;

	memset(p, 0, sizeof *p);

	p->img = img;
	p->r = r;
	p->dx = Dx(r);
	p->needbuf = needbuf;
	p->convgrey = convgrey;

	assert(img->r.min.x <= r.min.x && r.min.x < img->r.max.x);

	p->bytey0s = byteaddr(img, Pt(img->r.min.x, img->r.min.y));
	p->bytermin = byteaddr(img, Pt(r.min.x, img->r.min.y));
	p->bytey0e = byteaddr(img, Pt(img->r.max.x, img->r.min.y));
	p->bwidth = sizeof(u32int)*img->width;

	assert(p->bytey0s <= p->bytermin && p->bytermin <= p->bytey0e);

	if(p->r.min.x == p->img->r.min.x)
		assert(p->bytermin == p->bytey0s);

	nbuf = 1;
	if((img->flags&Frepl) && Dy(img->r) <= MAXBCACHE && Dy(img->r) < Dy(r)){
		p->replcache = 1;
		nbuf = Dy(img->r);
	}
	p->bufdelta = 4*p->dx;
	p->bufoff = ndrawbuf;
	ndrawbuf += p->bufdelta*nbuf;
}

static void
clipy(Memimage *img, int *y)
{
	int dy;

	dy = Dy(img->r);
	if(*y == dy)
		*y = 0;
	else if(*y == -1)
		*y = dy-1;
	assert(0 <= *y && *y < dy);
}

static void
dumpbuf(char *s, Buffer b, int n)
{
	int i;
	uchar *p;
	
	print("%s", s);
	for(i=0; i<n; i++){
		print(" ");
		if(p=b.grey){
			print(" k%.2uX", *p);
			b.grey += b.delta;
		}else{	
			if(p=b.red){
				print(" r%.2uX", *p);
				b.red += b.delta;
			}
			if(p=b.grn){
				print(" g%.2uX", *p);
				b.grn += b.delta;
			}
			if(p=b.blu){
				print(" b%.2uX", *p);
				b.blu += b.delta;
			}
		}
		if((p=b.alpha) != &ones){
			print(" α%.2uX", *p);
			b.alpha += b.delta;
		}
	}
	print("\n");
}

/*
 * For each scan line, we expand the pixels from source, mask, and destination
 * into byte-aligned red, green, blue, alpha, and grey channels.  If buffering is not
 * needed and the channels were already byte-aligned (grey8, rgb24, rgba32, rgb32),
 * the readers need not copy the data: they can simply return pointers to the data.
 * If the destination image is grey and the source is not, it is converted using the NTSC
 * formula.
 *
 * Once we have all the channels, we call either rgbcalc or greycalc, depending on 
 * whether the destination image is color.  This is allowed to overwrite the dst buffer (perhaps
 * the actual data, perhaps a copy) with its result.  It should only overwrite the dst buffer
 * with the same format (i.e. red bytes with red bytes, etc.)  A new buffer is returned from
 * the calculator, and that buffer is passed to a function to write it to the destination.
 * If the buffer is already pointing at the destination, the writing function is a no-op.
 */
#define DBG if(drawdebug)
static int
alphadraw(Memdrawparam *par)
{
	int isgrey, starty, endy, op;
	int needbuf, dsty, srcy, masky;
	int y, dir, dx, dy;
	Buffer bsrc, bdst, bmask;
	Readfn *rdsrc, *rdmask, *rddst;
	Calcfn *calc;
	Writefn *wrdst;
	Memimage *src, *mask, *dst;
	Rectangle r, sr, mr;

	if(drawdebug)
		print("alphadraw %R\n", par->r);
	r = par->r;
	dx = Dx(r);
	dy = Dy(r);

	ndrawbuf = 0;

	src = par->src;
	mask = par->mask;	
	dst = par->dst;
	sr = par->sr;
	mr = par->mr;
	op = par->op;

	isgrey = dst->flags&Fgrey;

	/*
	 * Buffering when src and dst are the same bitmap is sufficient but not 
	 * necessary.  There are stronger conditions we could use.  We could
	 * check to see if the rectangles intersect, and if simply moving in the
	 * correct y direction can avoid the need to buffer.
	 */
	needbuf = (src->data == dst->data);

	getparam(&spar, src, sr, isgrey, needbuf);
	getparam(&dpar, dst, r, isgrey, needbuf);
	getparam(&mpar, mask, mr, 0, needbuf);

	dir = (needbuf && byteaddr(dst, r.min) > byteaddr(src, sr.min)) ? -1 : 1;
	spar.dir = mpar.dir = dpar.dir = dir;

	/*
	 * If the mask is purely boolean, we can convert from src to dst format
	 * when we read src, and then just copy it to dst where the mask tells us to.
	 * This requires a boolean (1-bit grey) mask and lack of a source alpha channel.
	 *
	 * The computation is accomplished by assigning the function pointers as follows:
	 *	rdsrc - read and convert source into dst format in a buffer
	 * 	rdmask - convert mask to bytes, set pointer to it
	 * 	rddst - fill with pointer to real dst data, but do no reads
	 *	calc - copy src onto dst when mask says to.
	 *	wrdst - do nothing
	 * This is slightly sleazy, since things aren't doing exactly what their names say,
	 * but it avoids a fair amount of code duplication to make this a case here
	 * rather than have a separate booldraw.
	 */
/*if(drawdebug) iprint("flag %lud mchan %lux=?%x dd %d\n", src->flags&Falpha, mask->chan, GREY1, dst->depth); */
	if(!(src->flags&Falpha) && mask->chan == GREY1 && dst->depth >= 8 && op == SoverD){
/*if(drawdebug) iprint("boolcopy..."); */
		rdsrc = convfn(dst, &dpar, src, &spar);
		rddst = readptr;
		rdmask = readfn(mask);
		calc = boolcopyfn(dst, mask);
		wrdst = nullwrite;
	}else{
		/* usual alphadraw parameter fetching */
		rdsrc = readfn(src);
		rddst = readfn(dst);
		wrdst = writefn(dst);
		calc = alphacalc[op];

		/*
		 * If there is no alpha channel, we'll ask for a grey channel
		 * and pretend it is the alpha.
		 */
		if(mask->flags&Falpha){
			rdmask = readalphafn(mask);
			mpar.alphaonly = 1;
		}else{
			mpar.greymaskcall = readfn(mask);
			mpar.convgrey = 1;
			rdmask = greymaskread;

			/*
			 * Should really be above, but then boolcopyfns would have
			 * to deal with bit alignment, and I haven't written that.
			 *
			 * This is a common case for things like ellipse drawing.
			 * When there's no alpha involved and the mask is boolean,
			 * we can avoid all the division and multiplication.
			 */
			if(mask->chan == GREY1 && !(src->flags&Falpha))
				calc = boolcalc[op];
			else if(op == SoverD && !(src->flags&Falpha))
				calc = alphacalcS;
		}
	}

	/*
	 * If the image has a small enough repl rectangle,
	 * we can just read each line once and cache them.
	 */
	if(spar.replcache){
		spar.replcall = rdsrc;
		rdsrc = replread;
	}
	if(mpar.replcache){
		mpar.replcall = rdmask;
		rdmask = replread;
	}

	if(allocdrawbuf() < 0)
		return 0;

	/*
	 * Before we were saving only offsets from drawbuf in the parameter
	 * structures; now that drawbuf has been grown to accomodate us,
	 * we can fill in the pointers.
	 */
	spar.bufbase = drawbuf+spar.bufoff;
	mpar.bufbase = drawbuf+mpar.bufoff;
	dpar.bufbase = drawbuf+dpar.bufoff;
	spar.convbuf = drawbuf+spar.convbufoff;

	if(dir == 1){
		starty = 0;
		endy = dy;
	}else{
		starty = dy-1;
		endy = -1;
	}

	/*
	 * srcy, masky, and dsty are offsets from the top of their
	 * respective Rectangles.  they need to be contained within
	 * the rectangles, so clipy can keep them there without division.
 	 */
	srcy = (starty + sr.min.y - src->r.min.y)%Dy(src->r);
	masky = (starty + mr.min.y - mask->r.min.y)%Dy(mask->r);
	dsty = starty + r.min.y - dst->r.min.y;

	assert(0 <= srcy && srcy < Dy(src->r));
	assert(0 <= masky && masky < Dy(mask->r));
	assert(0 <= dsty && dsty < Dy(dst->r));

	if(drawdebug)
		print("alphadraw: rdsrc=%p rdmask=%p rddst=%p calc=%p wrdst=%p\n",
			rdsrc, rdmask, rddst, calc, wrdst);
	for(y=starty; y!=endy; y+=dir, srcy+=dir, masky+=dir, dsty+=dir){
		clipy(src, &srcy);
		clipy(dst, &dsty);
		clipy(mask, &masky);

		bsrc = rdsrc(&spar, spar.bufbase, srcy);
DBG print("[");
		bmask = rdmask(&mpar, mpar.bufbase, masky);
DBG print("]\n");
		bdst = rddst(&dpar, dpar.bufbase, dsty);
DBG		dumpbuf("src", bsrc, dx);
DBG		dumpbuf("mask", bmask, dx);
DBG		dumpbuf("dst", bdst, dx);
		bdst = calc(bdst, bsrc, bmask, dx, isgrey, op);
DBG		dumpbuf("bdst", bdst, dx);
		wrdst(&dpar, dpar.bytermin+dsty*dpar.bwidth, bdst);
	}

	return 1;
}
#undef DBG

static Buffer
alphacalc0(Buffer bdst, Buffer b1, Buffer b2, int dx, int grey, int op)
{
	USED(grey);
	USED(op);
	memset(bdst.rgba, 0, dx*bdst.delta);
	return bdst;
}

/*
 * Do the channels in the buffers match enough
 * that we can do word-at-a-time operations
 * on the pixels?
 */
static int
chanmatch(Buffer *bdst, Buffer *bsrc)
{
	uchar *drgb, *srgb;
	
	/*
	 * first, r, g, b must be in the same place
	 * in the rgba word.
	 */
	drgb = (uchar*)bdst->rgba;
	srgb = (uchar*)bsrc->rgba;
	if(bdst->red - drgb != bsrc->red - srgb
	|| bdst->blu - drgb != bsrc->blu - srgb
	|| bdst->grn - drgb != bsrc->grn - srgb)
		return 0;
	
	/*
	 * that implies alpha is in the same place,
	 * if it is there at all (it might be == &ones).
	 * if the destination is &ones, we can scribble
	 * over the rgba slot just fine.
	 */
	if(bdst->alpha == &ones)
		return 1;
	
	/*
	 * if the destination is not ones but the src is,
	 * then the simultaneous calculation will use
	 * bogus bytes from the src's rgba.  no good.
	 */
	if(bsrc->alpha == &ones)
		return 0;
	
	/*
	 * otherwise, alphas are in the same place.
	 */
	return 1;
}

static Buffer
alphacalc14(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
{
	Buffer obdst;
	int fd, sadelta;
	int i, sa, ma, q;
	u32int t, t1;

	obdst = bdst;
	sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
	q = bsrc.delta == 4 && bdst.delta == 4 && chanmatch(&bdst, &bsrc);

	for(i=0; i<dx; i++){
		sa = *bsrc.alpha;
		ma = *bmask.alpha;
		fd = CALC11(sa, ma, t);
		if(op == DoutS)
			fd = 255-fd;

		if(grey){
			*bdst.grey = CALC11(fd, *bdst.grey, t);
			bsrc.grey += bsrc.delta;
			bdst.grey += bdst.delta;
		}else{
			if(q){
				*bdst.rgba = CALC41(fd, *bdst.rgba, t, t1);
				bsrc.rgba++;
				bdst.rgba++;
				bsrc.alpha += sadelta;
				bmask.alpha += bmask.delta;
				continue;
			}
			*bdst.red = CALC11(fd, *bdst.red, t);
			*bdst.grn = CALC11(fd, *bdst.grn, t);
			*bdst.blu = CALC11(fd, *bdst.blu, t);
			bsrc.red += bsrc.delta;
			bsrc.blu += bsrc.delta;
			bsrc.grn += bsrc.delta;
			bdst.red += bdst.delta;
			bdst.blu += bdst.delta;
			bdst.grn += bdst.delta;
		}
		if(bdst.alpha != &ones){
			*bdst.alpha = CALC11(fd, *bdst.alpha, t);
			bdst.alpha += bdst.delta;
		}
		bmask.alpha += bmask.delta;
		bsrc.alpha += sadelta;
	}
	return obdst;
}

static Buffer
alphacalc2810(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
{
	Buffer obdst;
	int fs, sadelta;
	int i, ma, da, q;
	u32int t, t1;

	obdst = bdst;
	sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
	q = bsrc.delta == 4 && bdst.delta == 4 && chanmatch(&bdst, &bsrc);

	for(i=0; i<dx; i++){
		ma = *bmask.alpha;
		da = *bdst.alpha;
		if(op == SoutD)
			da = 255-da;
		fs = ma;
		if(op != S)
			fs = CALC11(fs, da, t);

		if(grey){
			*bdst.grey = CALC11(fs, *bsrc.grey, t);
			bsrc.grey += bsrc.delta;
			bdst.grey += bdst.delta;
		}else{
			if(q){
				*bdst.rgba = CALC41(fs, *bsrc.rgba, t, t1);
				bsrc.rgba++;
				bdst.rgba++;
				bmask.alpha += bmask.delta;
				bdst.alpha += bdst.delta;
				continue;
			}
			*bdst.red = CALC11(fs, *bsrc.red, t);
			*bdst.grn = CALC11(fs, *bsrc.grn, t);
			*bdst.blu = CALC11(fs, *bsrc.blu, t);
			bsrc.red += bsrc.delta;
			bsrc.blu += bsrc.delta;
			bsrc.grn += bsrc.delta;
			bdst.red += bdst.delta;
			bdst.blu += bdst.delta;
			bdst.grn += bdst.delta;
		}
		if(bdst.alpha != &ones){
			*bdst.alpha = CALC11(fs, *bsrc.alpha, t);
			bdst.alpha += bdst.delta;
		}
		bmask.alpha += bmask.delta;
		bsrc.alpha += sadelta;
	}
	return obdst;
}

static Buffer
alphacalc3679(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
{
	Buffer obdst;
	int fs, fd, sadelta;
	int i, sa, ma, da, q;
	u32int t, t1;

	obdst = bdst;
	sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
	q = bsrc.delta == 4 && bdst.delta == 4 && chanmatch(&bdst, &bsrc);

	for(i=0; i<dx; i++){
		sa = *bsrc.alpha;
		ma = *bmask.alpha;
		da = *bdst.alpha;
		if(op == SatopD)
			fs = CALC11(ma, da, t);
		else
			fs = CALC11(ma, 255-da, t);
		if(op == DoverS)
			fd = 255;
		else{
			fd = CALC11(sa, ma, t);
			if(op != DatopS)
				fd = 255-fd;
		}

		if(grey){
			*bdst.grey = CALC12(fs, *bsrc.grey, fd, *bdst.grey, t);
			bsrc.grey += bsrc.delta;
			bdst.grey += bdst.delta;
		}else{
			if(q){
				*bdst.rgba = CALC42(fs, *bsrc.rgba, fd, *bdst.rgba, t, t1);
				bsrc.rgba++;
				bdst.rgba++;
				bsrc.alpha += sadelta;
				bmask.alpha += bmask.delta;
				bdst.alpha += bdst.delta;
				continue;
			}
			*bdst.red = CALC12(fs, *bsrc.red, fd, *bdst.red, t);
			*bdst.grn = CALC12(fs, *bsrc.grn, fd, *bdst.grn, t);
			*bdst.blu = CALC12(fs, *bsrc.blu, fd, *bdst.blu, t);
			bsrc.red += bsrc.delta;
			bsrc.blu += bsrc.delta;
			bsrc.grn += bsrc.delta;
			bdst.red += bdst.delta;
			bdst.blu += bdst.delta;
			bdst.grn += bdst.delta;
		}
		if(bdst.alpha != &ones){
			*bdst.alpha = CALC12(fs, sa, fd, da, t);
			bdst.alpha += bdst.delta;
		}
		bmask.alpha += bmask.delta;
		bsrc.alpha += sadelta;
	}
	return obdst;
}

static Buffer
alphacalc5(Buffer bdst, Buffer b1, Buffer b2, int dx, int grey, int op)
{
	USED(dx);
	USED(grey);
	USED(op);
	return bdst;
}

static Buffer
alphacalc11(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
{
	Buffer obdst;
	int fd, sadelta;
	int i, sa, ma, q;
	u32int t, t1;

	USED(op);
	obdst = bdst;
	sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
	q = bsrc.delta == 4 && bdst.delta == 4 && chanmatch(&bdst, &bsrc);

	for(i=0; i<dx; i++){
		sa = *bsrc.alpha;
		ma = *bmask.alpha;
		fd = 255-CALC11(sa, ma, t);

		if(grey){
			*bdst.grey = CALC12(ma, *bsrc.grey, fd, *bdst.grey, t);
			bsrc.grey += bsrc.delta;
			bdst.grey += bdst.delta;
		}else{
			if(q){
				*bdst.rgba = CALC42(ma, *bsrc.rgba, fd, *bdst.rgba, t, t1);
				bsrc.rgba++;
				bdst.rgba++;
				bsrc.alpha += sadelta;
				bmask.alpha += bmask.delta;
				continue;
			}
			*bdst.red = CALC12(ma, *bsrc.red, fd, *bdst.red, t);
			*bdst.grn = CALC12(ma, *bsrc.grn, fd, *bdst.grn, t);
			*bdst.blu = CALC12(ma, *bsrc.blu, fd, *bdst.blu, t);
			bsrc.red += bsrc.delta;
			bsrc.blu += bsrc.delta;
			bsrc.grn += bsrc.delta;
			bdst.red += bdst.delta;
			bdst.blu += bdst.delta;
			bdst.grn += bdst.delta;
		}
		if(bdst.alpha != &ones){
			*bdst.alpha = CALC12(ma, sa, fd, *bdst.alpha, t);
			bdst.alpha += bdst.delta;
		}
		bmask.alpha += bmask.delta;
		bsrc.alpha += sadelta;
	}
	return obdst;
}

/*
not used yet
source and mask alpha 1
static Buffer
alphacalcS0(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
{
	Buffer obdst;
	int i;

	USED(op);
	obdst = bdst;
	if(bsrc.delta == bdst.delta){
		memmove(bdst.rgba, bsrc.rgba, dx*bdst.delta);
		return obdst;
	}
	for(i=0; i<dx; i++){
		if(grey){
			*bdst.grey = *bsrc.grey;
			bsrc.grey += bsrc.delta;
			bdst.grey += bdst.delta;
		}else{
			*bdst.red = *bsrc.red;
			*bdst.grn = *bsrc.grn;
			*bdst.blu = *bsrc.blu;
			bsrc.red += bsrc.delta;
			bsrc.blu += bsrc.delta;
			bsrc.grn += bsrc.delta;
			bdst.red += bdst.delta;
			bdst.blu += bdst.delta;
			bdst.grn += bdst.delta;
		}
		if(bdst.alpha != &ones){
			*bdst.alpha = 255;
			bdst.alpha += bdst.delta;
		}
	}
	return obdst;
}
*/

/* source alpha 1 */
static Buffer
alphacalcS(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
{
	Buffer obdst;
	int fd;
	int i, ma;
	u32int t;

	USED(op);
	obdst = bdst;

	for(i=0; i<dx; i++){
		ma = *bmask.alpha;
		fd = 255-ma;

		if(grey){
			*bdst.grey = CALC12(ma, *bsrc.grey, fd, *bdst.grey, t);
			bsrc.grey += bsrc.delta;
			bdst.grey += bdst.delta;
		}else{
			*bdst.red = CALC12(ma, *bsrc.red, fd, *bdst.red, t);
			*bdst.grn = CALC12(ma, *bsrc.grn, fd, *bdst.grn, t);
			*bdst.blu = CALC12(ma, *bsrc.blu, fd, *bdst.blu, t);
			bsrc.red += bsrc.delta;
			bsrc.blu += bsrc.delta;
			bsrc.grn += bsrc.delta;
			bdst.red += bdst.delta;
			bdst.blu += bdst.delta;
			bdst.grn += bdst.delta;
		}
		if(bdst.alpha != &ones){
			*bdst.alpha = ma+CALC11(fd, *bdst.alpha, t);
			bdst.alpha += bdst.delta;
		}
		bmask.alpha += bmask.delta;
	}
	return obdst;
}

static Buffer
boolcalc14(Buffer bdst, Buffer b1, Buffer bmask, int dx, int grey, int op)
{
	Buffer obdst;
	int i, ma, zero;

	obdst = bdst;

	for(i=0; i<dx; i++){
		ma = *bmask.alpha;
		zero = ma ? op == DoutS : op == DinS;

		if(grey){
			if(zero)
				*bdst.grey = 0;
			bdst.grey += bdst.delta;
		}else{
			if(zero)
				*bdst.red = *bdst.grn = *bdst.blu = 0;
			bdst.red += bdst.delta;
			bdst.blu += bdst.delta;
			bdst.grn += bdst.delta;
		}
		bmask.alpha += bmask.delta;
		if(bdst.alpha != &ones){
			if(zero)
				*bdst.alpha = 0;
			bdst.alpha += bdst.delta;
		}
	}
	return obdst;
}

static Buffer
boolcalc236789(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
{
	Buffer obdst;
	int fs, fd;
	int i, ma, da, zero;
	u32int t;

	obdst = bdst;
	zero = !(op&1);

	for(i=0; i<dx; i++){
		ma = *bmask.alpha;
		da = *bdst.alpha;
		fs = da;
		if(op&2)
			fs = 255-da;
		fd = 0;
		if(op&4)
			fd = 255;

		if(grey){
			if(ma)
				*bdst.grey = CALC12(fs, *bsrc.grey, fd, *bdst.grey, t);
			else if(zero)
				*bdst.grey = 0;
			bsrc.grey += bsrc.delta;
			bdst.grey += bdst.delta;
		}else{
			if(ma){
				*bdst.red = CALC12(fs, *bsrc.red, fd, *bdst.red, t);
				*bdst.grn = CALC12(fs, *bsrc.grn, fd, *bdst.grn, t);
				*bdst.blu = CALC12(fs, *bsrc.blu, fd, *bdst.blu, t);
			}
			else if(zero)
				*bdst.red = *bdst.grn = *bdst.blu = 0;
			bsrc.red += bsrc.delta;
			bsrc.blu += bsrc.delta;
			bsrc.grn += bsrc.delta;
			bdst.red += bdst.delta;
			bdst.blu += bdst.delta;
			bdst.grn += bdst.delta;
		}
		bmask.alpha += bmask.delta;
		if(bdst.alpha != &ones){
			if(ma)
				*bdst.alpha = fs+CALC11(fd, da, t);
			else if(zero)
				*bdst.alpha = 0;
			bdst.alpha += bdst.delta;
		}
	}
	return obdst;
}

static Buffer
boolcalc1011(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
{
	Buffer obdst;
	int i, ma, zero;

	obdst = bdst;
	zero = !(op&1);

	for(i=0; i<dx; i++){
		ma = *bmask.alpha;

		if(grey){
			if(ma)
				*bdst.grey = *bsrc.grey;
			else if(zero)
				*bdst.grey = 0;
			bsrc.grey += bsrc.delta;
			bdst.grey += bdst.delta;
		}else{
			if(ma){
				*bdst.red = *bsrc.red;
				*bdst.grn = *bsrc.grn;
				*bdst.blu = *bsrc.blu;
			}
			else if(zero)
				*bdst.red = *bdst.grn = *bdst.blu = 0;
			bsrc.red += bsrc.delta;
			bsrc.blu += bsrc.delta;
			bsrc.grn += bsrc.delta;
			bdst.red += bdst.delta;
			bdst.blu += bdst.delta;
			bdst.grn += bdst.delta;
		}
		bmask.alpha += bmask.delta;
		if(bdst.alpha != &ones){
			if(ma)
				*bdst.alpha = 255;
			else if(zero)
				*bdst.alpha = 0;
			bdst.alpha += bdst.delta;
		}
	}
	return obdst;
}
/*
 * Replicated cached scan line read.  Call the function listed in the Param,
 * but cache the result so that for replicated images we only do the work once.
 */
static Buffer
replread(Param *p, uchar *s, int y)
{
	Buffer *b;

	USED(s);
	b = &p->bcache[y];
	if((p->bfilled & (1<<y)) == 0){
		p->bfilled |= 1<<y;
		*b = p->replcall(p, p->bufbase+y*p->bufdelta, y);
	}
	return *b;
}

/*
 * Alpha reading function that simply relabels the grey pointer.
 */
static Buffer
greymaskread(Param *p, uchar *buf, int y)
{
	Buffer b;

	b = p->greymaskcall(p, buf, y);
	b.alpha = b.grey;
	return b;
}

#define DBG if(0)
static Buffer
readnbit(Param *p, uchar *buf, int y)
{
	Buffer b;
	Memimage *img;
	uchar *repl, *r, *w, *ow, bits;
	int i, n, sh, depth, x, dx, npack, nbits;

	memset(&b, 0, sizeof b);
	b.rgba = (u32int*)buf;
	b.grey = w = buf;
	b.red = b.blu = b.grn = w;
	b.alpha = &ones;
	b.delta = 1;

	dx = p->dx;
	img = p->img;
	depth = img->depth;
	repl = &replbit[depth][0];
	npack = 8/depth;
	sh = 8-depth;

	/* copy from p->r.min.x until end of repl rectangle */
	x = p->r.min.x;
	n = dx;
	if(n > p->img->r.max.x - x)
		n = p->img->r.max.x - x;

	r = p->bytermin + y*p->bwidth;
DBG print("readnbit dx %d %p=%p+%d*%d, *r=%d fetch %d ", dx, r, p->bytermin, y, p->bwidth, *r, n);
	bits = *r++;
	nbits = 8;
	if(i=x&(npack-1)){
DBG print("throwaway %d...", i);
		bits <<= depth*i;
		nbits -= depth*i;
	}
	for(i=0; i<n; i++){
		if(nbits == 0){
DBG print("(%.2ux)...", *r);
			bits = *r++;
			nbits = 8;
		}
		*w++ = repl[bits>>sh];
DBG print("bit %x...", repl[bits>>sh]);
		bits <<= depth;
		nbits -= depth;
	}
	dx -= n;
	if(dx == 0)
		return b;

	assert(x+i == p->img->r.max.x);

	/* copy from beginning of repl rectangle until where we were before. */
	x = p->img->r.min.x;
	n = dx;
	if(n > p->r.min.x - x)
		n = p->r.min.x - x;

	r = p->bytey0s + y*p->bwidth;
DBG print("x=%d r=%p...", x, r);
	bits = *r++;
	nbits = 8;
	if(i=x&(npack-1)){
		bits <<= depth*i;
		nbits -= depth*i;
	}
DBG print("nbits=%d...", nbits);
	for(i=0; i<n; i++){
		if(nbits == 0){
			bits = *r++;
			nbits = 8;
		}
		*w++ = repl[bits>>sh];
DBG print("bit %x...", repl[bits>>sh]);
		bits <<= depth;
		nbits -= depth;
DBG print("bits %x nbits %d...", bits, nbits);
	}
	dx -= n;
	if(dx == 0)
		return b;

	assert(dx > 0);
	/* now we have exactly one full scan line: just replicate the buffer itself until we are done */
	ow = buf;
	while(dx--)
		*w++ = *ow++;

	return b;
}
#undef DBG

#define DBG if(0)
static void
writenbit(Param *p, uchar *w, Buffer src)
{
	uchar *r;
	u32int bits;
	int i, sh, depth, npack, nbits, x, ex;

	assert(src.grey != nil && src.delta == 1);

	x = p->r.min.x;
	ex = x+p->dx;
	depth = p->img->depth;
	npack = 8/depth;

	i=x&(npack-1);
	bits = i ? (*w >> (8-depth*i)) : 0;
	nbits = depth*i;
	sh = 8-depth;
	r = src.grey;

	for(; x<ex; x++){
		bits <<= depth;
DBG print(" %x", *r);
		bits |= (*r++ >> sh);
		nbits += depth;
		if(nbits == 8){
			*w++ = bits;
			nbits = 0;
		}
	}

	if(nbits){
		sh = 8-nbits;
		bits <<= sh;
		bits |= *w & ((1<<sh)-1);
		*w = bits;
	}
DBG print("\n");
	return;
}
#undef DBG

static Buffer
readcmap(Param *p, uchar *buf, int y)
{
	Buffer b;
	int a, convgrey, copyalpha, dx, i, m;
	uchar *q, *cmap, *begin, *end, *r, *w;

	memset(&b, 0, sizeof b);
	begin = p->bytey0s + y*p->bwidth;
	r = p->bytermin + y*p->bwidth;
	end = p->bytey0e + y*p->bwidth;
	cmap = p->img->cmap->cmap2rgb;
	convgrey = p->convgrey;
	copyalpha = (p->img->flags&Falpha) ? 1 : 0;

	w = buf;
	dx = p->dx;
	if(copyalpha){
		b.alpha = buf++;
		a = p->img->shift[CAlpha]/8;
		m = p->img->shift[CMap]/8;
		for(i=0; i<dx; i++){
			*w++ = r[a];
			q = cmap+r[m]*3;
			r += 2;
			if(r == end)
				r = begin;
			if(convgrey){
				*w++ = RGB2K(q[0], q[1], q[2]);
			}else{
				*w++ = q[2];	/* blue */
				*w++ = q[1];	/* green */
				*w++ = q[0];	/* red */
			}
		}
	}else{
		b.alpha = &ones;
		for(i=0; i<dx; i++){
			q = cmap+*r++*3;
			if(r == end)
				r = begin;
			if(convgrey){
				*w++ = RGB2K(q[0], q[1], q[2]);
			}else{
				*w++ = q[2];	/* blue */
				*w++ = q[1];	/* green */
				*w++ = q[0];	/* red */
			}
		}
	}

	b.rgba = (u32int*)(buf-copyalpha);

	if(convgrey){
		b.grey = buf;
		b.red = b.blu = b.grn = buf;
		b.delta = 1+copyalpha;
	}else{
		b.blu = buf;
		b.grn = buf+1;
		b.red = buf+2;
		b.grey = nil;
		b.delta = 3+copyalpha;
	}
	return b;
}

static void
writecmap(Param *p, uchar *w, Buffer src)
{
	uchar *cmap, *red, *grn, *blu;
	int i, dx, delta;

	cmap = p->img->cmap->rgb2cmap;
	
	delta = src.delta;
	red= src.red;
	grn = src.grn;
	blu = src.blu;

	dx = p->dx;
	for(i=0; i<dx; i++, red+=delta, grn+=delta, blu+=delta)
		*w++ = cmap[(*red>>4)*256+(*grn>>4)*16+(*blu>>4)];
}

#define DBG if(drawdebug)
static Buffer
readbyte(Param *p, uchar *buf, int y)
{
	Buffer b;
	Memimage *img;
	int dx, isgrey, convgrey, alphaonly, copyalpha, i, nb;
	uchar *begin, *end, *r, *w, *rrepl, *grepl, *brepl, *arepl, *krepl;
	uchar ured, ugrn, ublu;
	u32int u;

	img = p->img;
	begin = p->bytey0s + y*p->bwidth;
	r = p->bytermin + y*p->bwidth;
	end = p->bytey0e + y*p->bwidth;

	w = buf;
	dx = p->dx;
	nb = img->depth/8;

	convgrey = p->convgrey;	/* convert rgb to grey */
	isgrey = img->flags&Fgrey;
	alphaonly = p->alphaonly;
	copyalpha = (img->flags&Falpha) ? 1 : 0;

	/* if we can, avoid processing everything */
	if(!(img->flags&Frepl) && !convgrey && (img->flags&Fbytes)){
		memset(&b, 0, sizeof b);
		if(p->needbuf){
			memmove(buf, r, dx*nb);
			r = buf;
		}
		b.rgba = (u32int*)r;
		if(copyalpha)
			b.alpha = r+img->shift[CAlpha]/8;
		else
			b.alpha = &ones;
		if(isgrey){
			b.grey = r+img->shift[CGrey]/8;
			b.red = b.grn = b.blu = b.grey;
		}else{
			b.red = r+img->shift[CRed]/8;
			b.grn = r+img->shift[CGreen]/8;
			b.blu = r+img->shift[CBlue]/8;
		}
		b.delta = nb;
		return b;
	}

	rrepl = replbit[img->nbits[CRed]];
	grepl = replbit[img->nbits[CGreen]];
	brepl = replbit[img->nbits[CBlue]];
	arepl = replbit[img->nbits[CAlpha]];
	krepl = replbit[img->nbits[CGrey]];

	for(i=0; i<dx; i++){
		u = r[0] | (r[1]<<8) | (r[2]<<16) | (r[3]<<24);
		if(copyalpha)
			*w++ = arepl[(u>>img->shift[CAlpha]) & img->mask[CAlpha]];

		if(isgrey)
			*w++ = krepl[(u >> img->shift[CGrey]) & img->mask[CGrey]];
		else if(!alphaonly){
			ured = rrepl[(u >> img->shift[CRed]) & img->mask[CRed]];
			ugrn = grepl[(u >> img->shift[CGreen]) & img->mask[CGreen]];
			ublu = brepl[(u >> img->shift[CBlue]) & img->mask[CBlue]];
			if(convgrey){
				*w++ = RGB2K(ured, ugrn, ublu);
			}else{
				*w++ = brepl[(u >> img->shift[CBlue]) & img->mask[CBlue]];
				*w++ = grepl[(u >> img->shift[CGreen]) & img->mask[CGreen]];
				*w++ = rrepl[(u >> img->shift[CRed]) & img->mask[CRed]];
			}
		}
		r += nb;
		if(r == end)
			r = begin;
	}
	
	b.alpha = copyalpha ? buf : &ones;
	b.rgba = (u32int*)buf;
	if(alphaonly){
		b.red = b.grn = b.blu = b.grey = nil;
		if(!copyalpha)
			b.rgba = nil;
		b.delta = 1;
	}else if(isgrey || convgrey){
		b.grey = buf+copyalpha;
		b.red = b.grn = b.blu = buf+copyalpha;
		b.delta = copyalpha+1;
	}else{
		b.blu = buf+copyalpha;
		b.grn = buf+copyalpha+1;
		b.grey = nil;
		b.red = buf+copyalpha+2;
		b.delta = copyalpha+3;
	}
	return b;
}
#undef DBG

#define DBG if(drawdebug)
static void
writebyte(Param *p, uchar *w, Buffer src)
{
	Memimage *img;
	int i, isalpha, isgrey, nb, delta, dx, adelta;
	uchar ff, *red, *grn, *blu, *grey, *alpha;
	u32int u, mask;

	img = p->img;

	red = src.red;
	grn = src.grn;
	blu = src.blu;
	alpha = src.alpha;
	delta = src.delta;
	grey = src.grey;
	dx = p->dx;

	nb = img->depth/8;
	mask = (nb==4) ? 0 : ~((1<<img->depth)-1);

	isalpha = img->flags&Falpha;
	isgrey = img->flags&Fgrey;
	adelta = src.delta;

	if(isalpha && (alpha == nil || alpha == &ones)){
		ff = 0xFF;
		alpha = &ff;
		adelta = 0;
	}

	for(i=0; i<dx; i++){
		u = w[0] | (w[1]<<8) | (w[2]<<16) | (w[3]<<24);
DBG print("u %.8lux...", u);
		u &= mask;
DBG print("&mask %.8lux...", u);
		if(isgrey){
			u |= ((*grey >> (8-img->nbits[CGrey])) & img->mask[CGrey]) << img->shift[CGrey];
DBG print("|grey %.8lux...", u);
			grey += delta;
		}else{
			u |= ((*red >> (8-img->nbits[CRed])) & img->mask[CRed]) << img->shift[CRed];
			u |= ((*grn >> (8-img->nbits[CGreen])) & img->mask[CGreen]) << img->shift[CGreen];
			u |= ((*blu >> (8-img->nbits[CBlue])) & img->mask[CBlue]) << img->shift[CBlue];
			red += delta;
			grn += delta;
			blu += delta;
DBG print("|rgb %.8lux...", u);
		}

		if(isalpha){
			u |= ((*alpha >> (8-img->nbits[CAlpha])) & img->mask[CAlpha]) << img->shift[CAlpha];
			alpha += adelta;
DBG print("|alpha %.8lux...", u);
		}

		w[0] = u;
		w[1] = u>>8;
		w[2] = u>>16;
		w[3] = u>>24;
DBG print("write back %.8lux...", u);
		w += nb;
	}
}
#undef DBG

static Readfn*
readfn(Memimage *img)
{
	if(img->depth < 8)
		return readnbit;
	if(img->nbits[CMap] == 8)
		return readcmap;
	return readbyte;
}

static Readfn*
readalphafn(Memimage *m)
{
	USED(m);
	return readbyte;
}

static Writefn*
writefn(Memimage *img)
{
	if(img->depth < 8)
		return writenbit;
	if(img->chan == CMAP8)
		return writecmap;
	return writebyte;
}

static void
nullwrite(Param *p, uchar *s, Buffer b)
{
	USED(p);
	USED(s);
}

static Buffer
readptr(Param *p, uchar *s, int y)
{
	Buffer b;
	uchar *q;

	USED(s);
	memset(&b, 0, sizeof b);
	q = p->bytermin + y*p->bwidth;
	b.red = q;	/* ptr to data */
	b.grn = b.blu = b.grey = b.alpha = nil;
	b.rgba = (u32int*)q;
	b.delta = p->img->depth/8;
	return b;
}

static Buffer
boolmemmove(Buffer bdst, Buffer bsrc, Buffer b1, int dx, int i, int o)
{
	USED(i);
	USED(o);
	memmove(bdst.red, bsrc.red, dx*bdst.delta);
	return bdst;
}

static Buffer
boolcopy8(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o)
{
	uchar *m, *r, *w, *ew;

	USED(i);
	USED(o);
	m = bmask.grey;
	w = bdst.red;
	r = bsrc.red;
	ew = w+dx;
	for(; w < ew; w++,r++)
		if(*m++)
			*w = *r;
	return bdst;	/* not used */
}

static Buffer
boolcopy16(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o)
{
	uchar *m;
	ushort *r, *w, *ew;

	USED(i);
	USED(o);
	m = bmask.grey;
	w = (ushort*)bdst.red;
	r = (ushort*)bsrc.red;
	ew = w+dx;
	for(; w < ew; w++,r++)
		if(*m++)
			*w = *r;
	return bdst;	/* not used */
}

static Buffer
boolcopy24(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o)
{
	uchar *m;
	uchar *r, *w, *ew;

	USED(i);
	USED(o);
	m = bmask.grey;
	w = bdst.red;
	r = bsrc.red;
	ew = w+dx*3;
	while(w < ew){
		if(*m++){
			*w++ = *r++;
			*w++ = *r++;
			*w++ = *r++;
		}else{
			w += 3;
			r += 3;
		}
	}
	return bdst;	/* not used */
}

static Buffer
boolcopy32(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o)
{
	uchar *m;
	u32int *r, *w, *ew;

	USED(i);
	USED(o);
	m = bmask.grey;
	w = (u32int*)bdst.red;
	r = (u32int*)bsrc.red;
	ew = w+dx;
	for(; w < ew; w++,r++)
		if(*m++)
			*w = *r;
	return bdst;	/* not used */
}

static Buffer
genconv(Param *p, uchar *buf, int y)
{
	Buffer b;
	int nb;
	uchar *r, *w, *ew;

	/* read from source into RGB format in convbuf */
	b = p->convreadcall(p, p->convbuf, y);

	/* write RGB format into dst format in buf */
	p->convwritecall(p->convdpar, buf, b);

	if(p->convdx){
		nb = p->convdpar->img->depth/8;
		r = buf;
		w = buf+nb*p->dx;
		ew = buf+nb*p->convdx;
		while(w<ew)
			*w++ = *r++;
	}

	b.red = buf;
	b.blu = b.grn = b.grey = b.alpha = nil;
	b.rgba = (u32int*)buf;
	b.delta = 0;
	
	return b;
}

static Readfn*
convfn(Memimage *dst, Param *dpar, Memimage *src, Param *spar)
{
	if(dst->chan == src->chan && !(src->flags&Frepl)){
/*if(drawdebug) iprint("readptr..."); */
		return readptr;
	}

	if(dst->chan==CMAP8 && (src->chan==GREY1||src->chan==GREY2||src->chan==GREY4)){
		/* cheat because we know the replicated value is exactly the color map entry. */
/*if(drawdebug) iprint("Readnbit..."); */
		return readnbit;
	}

	spar->convreadcall = readfn(src);
	spar->convwritecall = writefn(dst);
	spar->convdpar = dpar;

	/* allocate a conversion buffer */
	spar->convbufoff = ndrawbuf;
	ndrawbuf += spar->dx*4;

	if(spar->dx > Dx(spar->img->r)){
		spar->convdx = spar->dx;
		spar->dx = Dx(spar->img->r);
	}

/*if(drawdebug) iprint("genconv..."); */
	return genconv;
}

/*
 * Do NOT call this directly.  pixelbits is a wrapper
 * around this that fetches the bits from the X server
 * when necessary.
 */
u32int
_pixelbits(Memimage *i, Point pt)
{
	uchar *p;
	u32int val;
	int off, bpp, npack;

	val = 0;
	p = byteaddr(i, pt);
	switch(bpp=i->depth){
	case 1:
	case 2:
	case 4:
		npack = 8/bpp;
		off = pt.x%npack;
		val = p[0] >> bpp*(npack-1-off);
		val &= (1<<bpp)-1;
		break;
	case 8:
		val = p[0];
		break;
	case 16:
		val = p[0]|(p[1]<<8);
		break;
	case 24:
		val = p[0]|(p[1]<<8)|(p[2]<<16);
		break;
	case 32:
		val = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24);
		break;
	}
	while(bpp<32){
		val |= val<<bpp;
		bpp *= 2;
	}
	return val;
}

static Calcfn*
boolcopyfn(Memimage *img, Memimage *mask)
{
	if(mask->flags&Frepl && Dx(mask->r)==1 && Dy(mask->r)==1 && pixelbits(mask, mask->r.min)==~0)
		return boolmemmove;

	switch(img->depth){
	case 8:
		return boolcopy8;
	case 16:
		return boolcopy16;
	case 24:
		return boolcopy24;
	case 32:
		return boolcopy32;
	default:
		assert(0 /* boolcopyfn */);
	}
	return 0;
}

/*
 * Optimized draw for filling and scrolling; uses memset and memmove.
 */
static void
memsets(void *vp, ushort val, int n)
{
	ushort *p, *ep;

	p = vp;
	ep = p+n;
	while(p<ep)
		*p++ = val;
}

static void
memsetl(void *vp, u32int val, int n)
{
	u32int *p, *ep;

	p = vp;
	ep = p+n;
	while(p<ep)
		*p++ = val;
}

static void
memset24(void *vp, u32int val, int n)
{
	uchar *p, *ep;
	uchar a,b,c;

	p = vp;
	ep = p+3*n;
	a = val;
	b = val>>8;
	c = val>>16;
	while(p<ep){
		*p++ = a;
		*p++ = b;
		*p++ = c;
	}
}

u32int
_imgtorgba(Memimage *img, u32int val)
{
	uchar r, g, b, a;
	int nb, ov, v;
	u32int chan;
	uchar *p;

	a = 0xFF;
	r = g = b = 0xAA;	/* garbage */
	for(chan=img->chan; chan; chan>>=8){
		nb = NBITS(chan);
		ov = v = val&((1<<nb)-1);
		val >>= nb;

		while(nb < 8){
			v |= v<<nb;
			nb *= 2;
		}
		v >>= (nb-8);

		switch(TYPE(chan)){
		case CRed:
			r = v;
			break;
		case CGreen:
			g = v;
			break;
		case CBlue:
			b = v;
			break;
		case CAlpha:
			a = v;
			break;
		case CGrey:
			r = g = b = v;
			break;
		case CMap:
			p = img->cmap->cmap2rgb+3*ov;
			r = *p++;
			g = *p++;	
			b = *p;
			break;
		}
	}
	return (r<<24)|(g<<16)|(b<<8)|a;	
}

u32int
_rgbatoimg(Memimage *img, u32int rgba)
{
	u32int chan;
	int d, nb;
	u32int v;
	uchar *p, r, g, b, a, m;

	v = 0;
	r = rgba>>24;
	g = rgba>>16;
	b = rgba>>8;
	a = rgba;
	d = 0;
	for(chan=img->chan; chan; chan>>=8){
		nb = NBITS(chan);
		switch(TYPE(chan)){
		case CRed:
			v |= (r>>(8-nb))<<d;
			break;
		case CGreen:
			v |= (g>>(8-nb))<<d;
			break;
		case CBlue:
			v |= (b>>(8-nb))<<d;
			break;
		case CAlpha:
			v |= (a>>(8-nb))<<d;
			break;
		case CMap:
			p = img->cmap->rgb2cmap;
			m = p[(r>>4)*256+(g>>4)*16+(b>>4)];
			v |= (m>>(8-nb))<<d;
			break;
		case CGrey:
			m = RGB2K(r,g,b);
			v |= (m>>(8-nb))<<d;
			break;
		}
		d += nb;
	}
/*	print("rgba2img %.8lux = %.*lux\n", rgba, 2*d/8, v); */
	return v;
}

#define DBG if(0)
static int
memoptdraw(Memdrawparam *par)
{
	int m, y, dy, dx, op;
	u32int v;
	Memimage *src;
	Memimage *dst;

	dx = Dx(par->r);
	dy = Dy(par->r);
	src = par->src;
	dst = par->dst;
	op = par->op;

DBG print("state %lux mval %lux dd %d\n", par->state, par->mval, dst->depth);
	/*
	 * If we have an opaque mask and source is one opaque pixel we can convert to the
	 * destination format and just replicate with memset.
	 */
	m = Simplesrc|Simplemask|Fullmask;
	if((par->state&m)==m && (par->srgba&0xFF) == 0xFF && (op ==S || op == SoverD)){
		uchar *dp, p[4];
		int d, dwid, ppb, np, nb;
		uchar lm, rm;

DBG print("memopt, dst %p, dst->data->bdata %p\n", dst, dst->data->bdata);
		dwid = dst->width*sizeof(u32int);
		dp = byteaddr(dst, par->r.min);
		v = par->sdval;
DBG print("sdval %lud, depth %d\n", v, dst->depth);
		switch(dst->depth){
		case 1:
		case 2:
		case 4:
			for(d=dst->depth; d<8; d*=2)
				v |= (v<<d);
			ppb = 8/dst->depth;	/* pixels per byte */
			m = ppb-1;
			/* left edge */
			np = par->r.min.x&m;		/* no. pixels unused on left side of word */
			dx -= (ppb-np);
			nb = 8 - np * dst->depth;		/* no. bits used on right side of word */
			lm = (1<<nb)-1;
DBG print("np %d x %d nb %d lm %ux ppb %d m %ux\n", np, par->r.min.x, nb, lm, ppb, m);	

			/* right edge */
			np = par->r.max.x&m;	/* no. pixels used on left side of word */
			dx -= np;
			nb = 8 - np * dst->depth;		/* no. bits unused on right side of word */
			rm = ~((1<<nb)-1);
DBG print("np %d x %d nb %d rm %ux ppb %d m %ux\n", np, par->r.max.x, nb, rm, ppb, m);	

DBG print("dx %d Dx %d\n", dx, Dx(par->r));
			/* lm, rm are masks that are 1 where we should touch the bits */
			if(dx < 0){	/* just one byte */
				lm &= rm;
				for(y=0; y<dy; y++, dp+=dwid)
					*dp ^= (v ^ *dp) & lm;
			}else if(dx == 0){	/* no full bytes */
				if(lm)
					dwid--;

				for(y=0; y<dy; y++, dp+=dwid){
					if(lm){
DBG print("dp %p v %lux lm %ux (v ^ *dp) & lm %lux\n", dp, v, lm, (v^*dp)&lm);
						*dp ^= (v ^ *dp) & lm;
						dp++;
					}
					*dp ^= (v ^ *dp) & rm;
				}
			}else{		/* full bytes in middle */
				dx /= ppb;
				if(lm)
					dwid--;
				dwid -= dx;

				for(y=0; y<dy; y++, dp+=dwid){
					if(lm){
						*dp ^= (v ^ *dp) & lm;
						dp++;
					}
					memset(dp, v, dx);
					dp += dx;
					*dp ^= (v ^ *dp) & rm;
				}
			}
			return 1;
		case 8:
			for(y=0; y<dy; y++, dp+=dwid)
				memset(dp, v, dx);
			return 1;
		case 16:
			p[0] = v;		/* make little endian */
			p[1] = v>>8;
			v = *(ushort*)p;
DBG print("dp=%p; dx=%d; for(y=0; y<%d; y++, dp+=%d)\nmemsets(dp, v, dx);\n",
	dp, dx, dy, dwid);
			for(y=0; y<dy; y++, dp+=dwid)
				memsets(dp, v, dx);
			return 1;
		case 24:
			for(y=0; y<dy; y++, dp+=dwid)
				memset24(dp, v, dx);
			return 1;
		case 32:
			p[0] = v;		/* make little endian */
			p[1] = v>>8;
			p[2] = v>>16;
			p[3] = v>>24;
			v = *(u32int*)p;
			for(y=0; y<dy; y++, dp+=dwid)
				memsetl(dp, v, dx);
			return 1;
		default:
			assert(0 /* bad dest depth in memoptdraw */);
		}
	}

	/*
	 * If no source alpha, an opaque mask, we can just copy the
	 * source onto the destination.  If the channels are the same and
	 * the source is not replicated, memmove suffices.
	 */
	m = Simplemask|Fullmask;
	if((par->state&(m|Replsrc))==m && src->depth >= 8 
	&& src->chan == dst->chan && !(src->flags&Falpha) && (op == S || op == SoverD)){
		uchar *sp, *dp;
		long swid, dwid, nb;
		int dir;

		if(src->data == dst->data && byteaddr(dst, par->r.min) > byteaddr(src, par->sr.min))
			dir = -1;
		else
			dir = 1;

		swid = src->width*sizeof(u32int);
		dwid = dst->width*sizeof(u32int);
		sp = byteaddr(src, par->sr.min);
		dp = byteaddr(dst, par->r.min);
		if(dir == -1){
			sp += (dy-1)*swid;
			dp += (dy-1)*dwid;
			swid = -swid;
			dwid = -dwid;
		}
		nb = (dx*src->depth)/8;
		for(y=0; y<dy; y++, sp+=swid, dp+=dwid)
			memmove(dp, sp, nb);
		return 1;
	}

	/*
	 * If we have a 1-bit mask, 1-bit source, and 1-bit destination, and
	 * they're all bit aligned, we can just use bit operators.  This happens
	 * when we're manipulating boolean masks, e.g. in the arc code.
	 */
	if((par->state&(Simplemask|Simplesrc|Replmask|Replsrc))==0 
	&& dst->chan==GREY1 && src->chan==GREY1 && par->mask->chan==GREY1 
	&& (par->r.min.x&7)==(par->sr.min.x&7) && (par->r.min.x&7)==(par->mr.min.x&7)){
		uchar *sp, *dp, *mp;
		uchar lm, rm;
		long swid, dwid, mwid;
		int i, x, dir;

		sp = byteaddr(src, par->sr.min);
		dp = byteaddr(dst, par->r.min);
		mp = byteaddr(par->mask, par->mr.min);
		swid = src->width*sizeof(u32int);
		dwid = dst->width*sizeof(u32int);
		mwid = par->mask->width*sizeof(u32int);

		if(src->data == dst->data && byteaddr(dst, par->r.min) > byteaddr(src, par->sr.min)){
			dir = -1;
		}else
			dir = 1;

		lm = 0xFF>>(par->r.min.x&7);
		rm = 0xFF<<(8-(par->r.max.x&7));
		dx -= (8-(par->r.min.x&7)) + (par->r.max.x&7);

		if(dx < 0){	/* one byte wide */
			lm &= rm;
			if(dir == -1){
				dp += dwid*(dy-1);
				sp += swid*(dy-1);
				mp += mwid*(dy-1);
				dwid = -dwid;
				swid = -swid;
				mwid = -mwid;
			}
			for(y=0; y<dy; y++){
				*dp ^= (*dp ^ *sp) & *mp & lm;
				dp += dwid;
				sp += swid;
				mp += mwid;
			}
			return 1;
		}

		dx /= 8;
		if(dir == 1){
			i = (lm!=0)+dx+(rm!=0);
			mwid -= i;
			swid -= i;
			dwid -= i;
			for(y=0; y<dy; y++, dp+=dwid, sp+=swid, mp+=mwid){
				if(lm){
					*dp ^= (*dp ^ *sp++) & *mp++ & lm;
					dp++;
				}
				for(x=0; x<dx; x++){
					*dp ^= (*dp ^ *sp++) & *mp++;
					dp++;
				}
				if(rm){
					*dp ^= (*dp ^ *sp++) & *mp++ & rm;
					dp++;
				}
			}
			return 1;
		}else{
		/* dir == -1 */
			i = (lm!=0)+dx+(rm!=0);
			dp += dwid*(dy-1)+i-1;
			sp += swid*(dy-1)+i-1;
			mp += mwid*(dy-1)+i-1;
			dwid = -dwid+i;
			swid = -swid+i;
			mwid = -mwid+i;
			for(y=0; y<dy; y++, dp+=dwid, sp+=swid, mp+=mwid){
				if(rm){
					*dp ^= (*dp ^ *sp--) & *mp-- & rm;
					dp--;
				}
				for(x=0; x<dx; x++){
					*dp ^= (*dp ^ *sp--) & *mp--;
					dp--;
				}
				if(lm){
					*dp ^= (*dp ^ *sp--) & *mp-- & lm;
					dp--;
				}
			}
		}
		return 1;
	}
	return 0;	
}
#undef DBG

/*
 * Boolean character drawing.
 * Solid opaque color through a 1-bit greyscale mask.
 */
#define DBG if(0)
static int
chardraw(Memdrawparam *par)
{
	u32int bits;
	int i, ddepth, dy, dx, x, bx, ex, y, npack, bsh, depth, op;
	u32int v, maskwid, dstwid;
	uchar *wp, *rp, *q, *wc;
	ushort *ws;
	u32int *wl;
	uchar sp[4];
	Rectangle r, mr;
	Memimage *mask, *src, *dst;

if(0) if(drawdebug) iprint("chardraw? mf %lux md %d sf %lux dxs %d dys %d dd %d ddat %p sdat %p\n",
		par->mask->flags, par->mask->depth, par->src->flags, 
		Dx(par->src->r), Dy(par->src->r), par->dst->depth, par->dst->data, par->src->data);

	mask = par->mask;
	src = par->src;
	dst = par->dst;
	r = par->r;
	mr = par->mr;
	op = par->op;

	if((par->state&(Replsrc|Simplesrc|Fullsrc|Replmask)) != (Replsrc|Simplesrc|Fullsrc)
	|| mask->depth != 1 || dst->depth<8 || dst->data==src->data
	|| op != SoverD)
		return 0;

/*if(drawdebug) iprint("chardraw..."); */

	depth = mask->depth;
	maskwid = mask->width*sizeof(u32int);
	rp = byteaddr(mask, mr.min);
	npack = 8/depth;
	bsh = (mr.min.x % npack) * depth;

	wp = byteaddr(dst, r.min);
	dstwid = dst->width*sizeof(u32int);
DBG print("bsh %d\n", bsh);
	dy = Dy(r);
	dx = Dx(r);

	ddepth = dst->depth;

	/*
	 * for loop counts from bsh to bsh+dx
	 *
	 * we want the bottom bits to be the amount
	 * to shift the pixels down, so for n≡0 (mod 8) we want 
	 * bottom bits 7.  for n≡1, 6, etc.
	 * the bits come from -n-1.
	 */

	bx = -bsh-1;
	ex = -bsh-1-dx;
	SET(bits);
	v = par->sdval;

	/* make little endian */
	sp[0] = v;
	sp[1] = v>>8;
	sp[2] = v>>16;
	sp[3] = v>>24;

/*print("sp %x %x %x %x\n", sp[0], sp[1], sp[2], sp[3]); */
	for(y=0; y<dy; y++, rp+=maskwid, wp+=dstwid){
		q = rp;
		if(bsh)
			bits = *q++;
		switch(ddepth){
		case 8:
/*if(drawdebug) iprint("8loop..."); */
			wc = wp;
			for(x=bx; x>ex; x--, wc++){
				i = x&7;
				if(i == 8-1)
					bits = *q++;
DBG print("bits %lux sh %d...", bits, i);
				if((bits>>i)&1)
					*wc = v;
			}
			break;
		case 16:
			ws = (ushort*)wp;
			v = *(ushort*)sp;
			for(x=bx; x>ex; x--, ws++){
				i = x&7;
				if(i == 8-1)
					bits = *q++;
DBG print("bits %lux sh %d...", bits, i);
				if((bits>>i)&1)
					*ws = v;
			}
			break;
		case 24:
			wc = wp;
			for(x=bx; x>ex; x--, wc+=3){
				i = x&7;
				if(i == 8-1)
					bits = *q++;
DBG print("bits %lux sh %d...", bits, i);
				if((bits>>i)&1){
					wc[0] = sp[0];
					wc[1] = sp[1];
					wc[2] = sp[2];
				}
			}
			break;
		case 32:
			wl = (u32int*)wp;
			v = *(u32int*)sp;
			for(x=bx; x>ex; x--, wl++){
				i = x&7;
				if(i == 8-1)
					bits = *q++;
DBG iprint("bits %lux sh %d...", bits, i);
				if((bits>>i)&1)
					*wl = v;
			}
			break;
		}
	}

DBG print("\n");	
	return 1;	
}
#undef DBG


/*
 * Fill entire byte with replicated (if necessary) copy of source pixel,
 * assuming destination ldepth is >= source ldepth.
 *
 * This code is just plain wrong for >8bpp.
 *
u32int
membyteval(Memimage *src)
{
	int i, val, bpp;
	uchar uc;

	unloadmemimage(src, src->r, &uc, 1);
	bpp = src->depth;
	uc <<= (src->r.min.x&(7/src->depth))*src->depth;
	uc &= ~(0xFF>>bpp);
	* pixel value is now in high part of byte. repeat throughout byte 
	val = uc;
	for(i=bpp; i<8; i<<=1)
		val |= val>>i;
	return val;
}
 * 
 */

void
_memfillcolor(Memimage *i, u32int val)
{
	u32int bits;
	int d, y;
	uchar p[4];

	if(val == DNofill)
		return;

	bits = _rgbatoimg(i, val);
	switch(i->depth){
	case 24:	/* 24-bit images suck */
		for(y=i->r.min.y; y<i->r.max.y; y++)
			memset24(byteaddr(i, Pt(i->r.min.x, y)), bits, Dx(i->r));
		break;
	default:	/* 1, 2, 4, 8, 16, 32 */
		for(d=i->depth; d<32; d*=2)
			bits = (bits << d) | bits;
		p[0] = bits;		/* make little endian */
		p[1] = bits>>8;
		p[2] = bits>>16;
		p[3] = bits>>24;
		bits = *(u32int*)p;
		memsetl(wordaddr(i, i->r.min), bits, i->width*Dy(i->r));
		break;
	}
}

