⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drawtest.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#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*((ulong)(r))+587*((ulong)(g))+114*((ulong)(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, ulong nv);ulong 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;ulong	*savedstbits;voidrdb(void){}intiprint(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;}voidmain(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(ulong)*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 voidBprintr5g6b5(Biobuf *bio, char*, ulong 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 voidBprintr5g5b5a1(Biobuf *bio, char*, ulong 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);}voiddumpimage(char *name, Memimage *img, void *vdata, Point labelpt){	Biobuf b;	uchar *data;	uchar *p;	char *arg;	void (*fmt)(Biobuf*, char*, ulong);	int npr, x, y, nb, bpp;	ulong v, mask;	Rectangle r;	fmt = nil;	arg = nil;	switch(img->depth){	case 1:	case 2:	case 4:		fmt = (void(*)(Biobuf*,char*,ulong))Bprint;		arg = "%.1ux";		break;	case 8:		fmt = (void(*)(Biobuf*,char*,ulong))Bprint;		arg = "%.2ux";		break;	case 16:		arg = nil;		if(img->chan == RGB16)			fmt = Bprintr5g6b5;		else{			fmt = (void(*)(Biobuf*,char*,ulong))Bprint;			arg = "%.4ux";		}		break;	case 24:		fmt = (void(*)(Biobuf*,char*,ulong))Bprint;		arg = "%.6lux";		break;	case 32:		fmt = (void(*)(Biobuf*,char*,ulong))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 |= (ulong)(*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. */voidcheckone(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.yvoidcheckline(Rectangle r, Point sp, Point mp, int y, Memimage *stmp, Memimage *mtmp){	ulong *dp;	int nb;	ulong *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. */voidfill(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 */voidverifyonemask(void){	Point dp, sp, mp;	fill(dst, dstbits);	fill(src, srcbits);	memmove(dst->data->bdata, dstbits, dst->width*sizeof(ulong)*Yrange);	memmove(src->data->bdata, srcbits, src->width*sizeof(ulong)*Yrange);	memmove(mask->data->bdata, maskbits, mask->width*sizeof(ulong)*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(ulong)*Yrange);	memmove(savedstbits, dst->data->bdata, dst->width*sizeof(ulong)*Yrange);		memmove(dst->data->bdata, dstbits, dst->width*sizeof(ulong)*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(ulong)*Yrange);	checkone(dp, sp, mp);}voidverifyone(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 */voidverifylinemask(void){	Point sp, mp, tp, up;	Rectangle dr;	int x;	fill(dst, dstbits);	fill(src, srcbits);	memmove(dst->data->bdata, dstbits, dst->width*sizeof(ulong)*Yrange);	memmove(src->data->bdata, srcbits, src->width*sizeof(ulong)*Yrange);	memmove(mask->data->bdata, maskbits, mask->width*sizeof(ulong)*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(ulong)*Yrange);	memmove(dst->data->bdata, dstbits, dst->width*sizeof(ulong)*Yrange);	memimagedraw(dst, dr, src, sp, mask, mp, SoverD);	checkline(dr, drawrepl(src->r, sp), drawrepl(mask->r, mp), dr.min.y, nil, nil);}voidverifyline(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 */voidverifyrectmask(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(ulong)*Yrange);	memmove(src->data->bdata, srcbits, src->width*sizeof(ulong)*Yrange);	memmove(mask->data->bdata, maskbits, mask->width*sizeof(ulong)*Yrange);	dr.min.x = nrand(Xrange-1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -