xref: /inferno-os/appl/lib/readxbitmap.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsythimplement RImagefile;
2*37da2899SCharles.Forsyth
3*37da2899SCharles.Forsythinclude "sys.m";
4*37da2899SCharles.Forsyth	sys: Sys;
5*37da2899SCharles.Forsyth
6*37da2899SCharles.Forsythinclude "draw.m";
7*37da2899SCharles.Forsyth	draw: Draw;
8*37da2899SCharles.Forsyth
9*37da2899SCharles.Forsythinclude "bufio.m";
10*37da2899SCharles.Forsyth	bufio: Bufio;
11*37da2899SCharles.Forsyth	Iobuf: import bufio;
12*37da2899SCharles.Forsyth
13*37da2899SCharles.Forsythinclude "imagefile.m";
14*37da2899SCharles.Forsyth
15*37da2899SCharles.Forsythinit(iomod: Bufio)
16*37da2899SCharles.Forsyth{
17*37da2899SCharles.Forsyth	if(sys == nil)
18*37da2899SCharles.Forsyth		sys = load Sys Sys->PATH;
19*37da2899SCharles.Forsyth	bufio = iomod;
20*37da2899SCharles.Forsyth}
21*37da2899SCharles.Forsyth
22*37da2899SCharles.Forsythreadmulti(fd: ref Iobuf): (array of ref Rawimage, string)
23*37da2899SCharles.Forsyth{
24*37da2899SCharles.Forsyth	(i, err) := read(fd);
25*37da2899SCharles.Forsyth	if(i != nil){
26*37da2899SCharles.Forsyth		a := array[1] of { i };
27*37da2899SCharles.Forsyth		return (a, err);
28*37da2899SCharles.Forsyth	}
29*37da2899SCharles.Forsyth	return (nil, err);
30*37da2899SCharles.Forsyth}
31*37da2899SCharles.Forsyth
32*37da2899SCharles.Forsythread(fd: ref Iobuf): (ref Rawimage, string)
33*37da2899SCharles.Forsyth{
34*37da2899SCharles.Forsyth	width, height, fnd: int;
35*37da2899SCharles.Forsyth	(fnd, width) = get_define(fd);
36*37da2899SCharles.Forsyth	if(fnd)
37*37da2899SCharles.Forsyth		(fnd, height) = get_define(fd);
38*37da2899SCharles.Forsyth	if(!fnd)
39*37da2899SCharles.Forsyth		return (nil, "xbitmap doesn't start with width and height");
40*37da2899SCharles.Forsyth	if(height <= 0 || width <= 0)
41*37da2899SCharles.Forsyth		return (nil, "xbitmap has bad width or height");
42*37da2899SCharles.Forsyth	# now, optional x_hot, y_hot
43*37da2899SCharles.Forsyth	(fnd, nil) = get_define(fd);
44*37da2899SCharles.Forsyth	if(fnd)
45*37da2899SCharles.Forsyth		(fnd, nil) = get_define(fd);
46*37da2899SCharles.Forsyth	# now expect 'static char x...x_bits[] = {'
47*37da2899SCharles.Forsyth	if(!get_to_char(fd, '{'))
48*37da2899SCharles.Forsyth		return (nil, "xbitmap premature eof");
49*37da2899SCharles.Forsyth
50*37da2899SCharles.Forsyth	bytesperline := (width+7) / 8;
51*37da2899SCharles.Forsyth	pixels := array[width*height] of byte;
52*37da2899SCharles.Forsyth	pixi := 0;
53*37da2899SCharles.Forsyth	for(i := 0; i < height; i++) {
54*37da2899SCharles.Forsyth		for(j := 0; j < bytesperline; j++) {
55*37da2899SCharles.Forsyth			(vfnd, v) := get_hexbyte(fd);
56*37da2899SCharles.Forsyth			if(!vfnd)
57*37da2899SCharles.Forsyth				return (nil,  "xbitmap premature eof");
58*37da2899SCharles.Forsyth			kend := 7;
59*37da2899SCharles.Forsyth			if(j == bytesperline-1)
60*37da2899SCharles.Forsyth				kend = (width-1)%8;
61*37da2899SCharles.Forsyth			for(k := 0; k <= kend; k++) {
62*37da2899SCharles.Forsyth				if(v & (1<<k))
63*37da2899SCharles.Forsyth					pixels[pixi] = byte 0;
64*37da2899SCharles.Forsyth				else
65*37da2899SCharles.Forsyth					pixels[pixi] = byte 1;
66*37da2899SCharles.Forsyth				pixi++;
67*37da2899SCharles.Forsyth			}
68*37da2899SCharles.Forsyth		}
69*37da2899SCharles.Forsyth	}
70*37da2899SCharles.Forsyth	cmap := array[6] of {byte 0, byte 0, byte 0,
71*37da2899SCharles.Forsyth			byte 255, byte 255, byte 255};
72*37da2899SCharles.Forsyth	chans := array[1] of {pixels};
73*37da2899SCharles.Forsyth	ans := ref Rawimage(Draw->Rect((0,0),(width,height)), cmap, 0, byte 0, 1, chans, CRGB1, 0);
74*37da2899SCharles.Forsyth	return (ans, "");
75*37da2899SCharles.Forsyth}
76*37da2899SCharles.Forsyth
77*37da2899SCharles.Forsyth# get a line, which should be of form
78*37da2899SCharles.Forsyth#	'#define fieldname val'
79*37da2899SCharles.Forsyth# and return (found, integer rep of val)
80*37da2899SCharles.Forsythget_define(fd: ref Iobuf) : (int, int)
81*37da2899SCharles.Forsyth{
82*37da2899SCharles.Forsyth	c := fd.getc();
83*37da2899SCharles.Forsyth	if(c != '#') {
84*37da2899SCharles.Forsyth		fd.ungetc();
85*37da2899SCharles.Forsyth		return (0, 0);
86*37da2899SCharles.Forsyth	}
87*37da2899SCharles.Forsyth	line := fd.gets('\n');
88*37da2899SCharles.Forsyth	for(i := len line -1; i >= 0; i--)
89*37da2899SCharles.Forsyth		if(line[i] == ' ')
90*37da2899SCharles.Forsyth			break;
91*37da2899SCharles.Forsyth	val := int line[i+1:];
92*37da2899SCharles.Forsyth	return (1, val);
93*37da2899SCharles.Forsyth}
94*37da2899SCharles.Forsyth
95*37da2899SCharles.Forsyth# read fd until get char cterm; return 1 if found
96*37da2899SCharles.Forsythget_to_char(fd: ref Iobuf, cterm: int) : int
97*37da2899SCharles.Forsyth{
98*37da2899SCharles.Forsyth	for(;;) {
99*37da2899SCharles.Forsyth		c := fd.getc();
100*37da2899SCharles.Forsyth		if(c < 0)
101*37da2899SCharles.Forsyth			return c;
102*37da2899SCharles.Forsyth		if(c == cterm)
103*37da2899SCharles.Forsyth			return 1;
104*37da2899SCharles.Forsyth	}
105*37da2899SCharles.Forsyth}
106*37da2899SCharles.Forsyth
107*37da2899SCharles.Forsyth# read fd until get xDD, were DD are hex digits.
108*37da2899SCharles.Forsyth# return (found, value of DD as integer)
109*37da2899SCharles.Forsythget_hexbyte(fd: ref Iobuf) : (int, int)
110*37da2899SCharles.Forsyth{
111*37da2899SCharles.Forsyth	if(!get_to_char(fd, 'x'))
112*37da2899SCharles.Forsyth		return (0, 0);
113*37da2899SCharles.Forsyth	n1 := hexdig(fd.getc());
114*37da2899SCharles.Forsyth	n2 := hexdig(fd.getc());
115*37da2899SCharles.Forsyth	if(n1 < 0 || n2 < 0)
116*37da2899SCharles.Forsyth		return (0, 0);
117*37da2899SCharles.Forsyth	return (1, (n1<<4) | n2);
118*37da2899SCharles.Forsyth}
119*37da2899SCharles.Forsyth
120*37da2899SCharles.Forsythhexdig(c: int) : int
121*37da2899SCharles.Forsyth{
122*37da2899SCharles.Forsyth	if('0' <= c && c <= '9')
123*37da2899SCharles.Forsyth		c -= '0';
124*37da2899SCharles.Forsyth	else if('a' <= c && c <= 'f')
125*37da2899SCharles.Forsyth		c += 10 - 'a';
126*37da2899SCharles.Forsyth	else if('A' <= c && c <= 'F')
127*37da2899SCharles.Forsyth		c += 10 - 'A';
128*37da2899SCharles.Forsyth	else
129*37da2899SCharles.Forsyth		c = -1;
130*37da2899SCharles.Forsyth	return c;
131*37da2899SCharles.Forsyth}
132