forsyth20121205-174063a80cc13 years agoHistory
131 lines · 2.6 KB · Brainfuck
RawDownload
implement RImagefile; include "sys.m";	sys: Sys; include "draw.m";	draw: Draw; include "bufio.m";	bufio: Bufio;	Iobuf: import bufio; include "imagefile.m"; init(iomod: Bufio){	if(sys == nil)		sys = load Sys Sys->PATH;	bufio = iomod;} readmulti(fd: ref Iobuf): (array of ref Rawimage, string){	(i, err) := read(fd);	if(i != nil){		a := array[1] of { i };		return (a, err);	}	return (nil, err);} read(fd: ref Iobuf): (ref Rawimage, string){	width, height, fnd: int;	(fnd, width) = get_define(fd);	if(fnd)		(fnd, height) = get_define(fd);	if(!fnd)		return (nil, "xbitmap doesn't start with width and height");	if(height <= 0 || width <= 0)		return (nil, "xbitmap has bad width or height");	# now, optional x_hot, y_hot	(fnd, nil) = get_define(fd);	if(fnd)		(fnd, nil) = get_define(fd);	# now expect 'static char x...x_bits[] = {'	if(!get_to_char(fd, '{'))		return (nil, "xbitmap premature eof"); 	bytesperline := (width+7) / 8;	pixels := array[width*height] of byte;	pixi := 0;	for(i := 0; i < height; i++) {		for(j := 0; j < bytesperline; j++) {			(vfnd, v) := get_hexbyte(fd);			if(!vfnd)				return (nil,  "xbitmap premature eof");			kend := 7;			if(j == bytesperline-1)				kend = (width-1)%8;			for(k := 0; k <= kend; k++) {				if(v & (1<<k))					pixels[pixi] = byte 0;				else					pixels[pixi] = byte 1;				pixi++;			}		}	}	cmap := array[6] of {byte 0, byte 0, byte 0,			byte 255, byte 255, byte 255};	chans := array[1] of {pixels};	ans := ref Rawimage(Draw->Rect((0,0),(width,height)), cmap, 0, byte 0, 1, chans, CRGB1, 0);	return (ans, "");} # get a line, which should be of form#	'#define fieldname val'# and return (found, integer rep of val)get_define(fd: ref Iobuf) : (int, int){	c := fd.getc();	if(c != '#') {		fd.ungetc();		return (0, 0);	}	line := fd.gets('\n');	for(i := len line -1; i >= 0; i--)		if(line[i] == ' ')			break;	val := int line[i+1:];	return (1, val);} # read fd until get char cterm; return 1 if foundget_to_char(fd: ref Iobuf, cterm: int) : int{	for(;;) {		c := fd.getc();		if(c < 0)			return c;		if(c == cterm)			return 1;	}} # read fd until get xDD, were DD are hex digits.# return (found, value of DD as integer)get_hexbyte(fd: ref Iobuf) : (int, int){	if(!get_to_char(fd, 'x'))		return (0, 0);	n1 := hexdig(fd.getc());	n2 := hexdig(fd.getc());	if(n1 < 0 || n2 < 0)		return (0, 0);	return (1, (n1<<4) | n2);} hexdig(c: int) : int{	if('0' <= c && c <= '9')		c -= '0';	else if('a' <= c && c <= 'f')		c += 10 - 'a';	else if('A' <= c && c <= 'F')		c += 10 - 'A';	else		c = -1;	return c;}