xref: /inferno-os/libmemdraw/load.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth #include "lib9.h"
2*37da2899SCharles.Forsyth #include "draw.h"
3*37da2899SCharles.Forsyth #include "memdraw.h"
4*37da2899SCharles.Forsyth 
5*37da2899SCharles.Forsyth int
loadmemimage(Memimage * i,Rectangle r,uchar * data,int ndata)6*37da2899SCharles.Forsyth loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata)
7*37da2899SCharles.Forsyth {
8*37da2899SCharles.Forsyth 	int y, l, lpart, rpart, mx, m, mr;
9*37da2899SCharles.Forsyth 	uchar *q;
10*37da2899SCharles.Forsyth 
11*37da2899SCharles.Forsyth 	if(!rectinrect(r, i->r))
12*37da2899SCharles.Forsyth 		return -1;
13*37da2899SCharles.Forsyth 	l = bytesperline(r, i->depth);
14*37da2899SCharles.Forsyth 	if(ndata < l*Dy(r))
15*37da2899SCharles.Forsyth 		return -1;
16*37da2899SCharles.Forsyth 	ndata = l*Dy(r);
17*37da2899SCharles.Forsyth 	q = byteaddr(i, r.min);
18*37da2899SCharles.Forsyth 	mx = 7/i->depth;
19*37da2899SCharles.Forsyth 	lpart = (r.min.x & mx) * i->depth;
20*37da2899SCharles.Forsyth 	rpart = (r.max.x & mx) * i->depth;
21*37da2899SCharles.Forsyth 	m = 0xFF >> lpart;
22*37da2899SCharles.Forsyth 	/* may need to do bit insertion on edges */
23*37da2899SCharles.Forsyth 	if(l == 1){	/* all in one byte */
24*37da2899SCharles.Forsyth 		if(rpart)
25*37da2899SCharles.Forsyth 			m ^= 0xFF >> rpart;
26*37da2899SCharles.Forsyth 		for(y=r.min.y; y<r.max.y; y++){
27*37da2899SCharles.Forsyth 			*q ^= (*data^*q) & m;
28*37da2899SCharles.Forsyth 			q += i->width*sizeof(ulong);
29*37da2899SCharles.Forsyth 			data++;
30*37da2899SCharles.Forsyth 		}
31*37da2899SCharles.Forsyth 		return ndata;
32*37da2899SCharles.Forsyth 	}
33*37da2899SCharles.Forsyth 	if(lpart==0 && rpart==0){	/* easy case */
34*37da2899SCharles.Forsyth 		for(y=r.min.y; y<r.max.y; y++){
35*37da2899SCharles.Forsyth 			memmove(q, data, l);
36*37da2899SCharles.Forsyth 			q += i->width*sizeof(ulong);
37*37da2899SCharles.Forsyth 			data += l;
38*37da2899SCharles.Forsyth 		}
39*37da2899SCharles.Forsyth 		return ndata;
40*37da2899SCharles.Forsyth 	}
41*37da2899SCharles.Forsyth 	mr = 0xFF ^ (0xFF >> rpart);
42*37da2899SCharles.Forsyth 	if(lpart!=0 && rpart==0){
43*37da2899SCharles.Forsyth 		for(y=r.min.y; y<r.max.y; y++){
44*37da2899SCharles.Forsyth 			*q ^= (*data^*q) & m;
45*37da2899SCharles.Forsyth 			if(l > 1)
46*37da2899SCharles.Forsyth 				memmove(q+1, data+1, l-1);
47*37da2899SCharles.Forsyth 			q += i->width*sizeof(ulong);
48*37da2899SCharles.Forsyth 			data += l;
49*37da2899SCharles.Forsyth 		}
50*37da2899SCharles.Forsyth 		return ndata;
51*37da2899SCharles.Forsyth 	}
52*37da2899SCharles.Forsyth 	if(lpart==0 && rpart!=0){
53*37da2899SCharles.Forsyth 		for(y=r.min.y; y<r.max.y; y++){
54*37da2899SCharles.Forsyth 			if(l > 1)
55*37da2899SCharles.Forsyth 				memmove(q, data, l-1);
56*37da2899SCharles.Forsyth 			q[l-1] ^= (data[l-1]^q[l-1]) & mr;
57*37da2899SCharles.Forsyth 			q += i->width*sizeof(ulong);
58*37da2899SCharles.Forsyth 			data += l;
59*37da2899SCharles.Forsyth 		}
60*37da2899SCharles.Forsyth 		return ndata;
61*37da2899SCharles.Forsyth 	}
62*37da2899SCharles.Forsyth 	for(y=r.min.y; y<r.max.y; y++){
63*37da2899SCharles.Forsyth 		*q ^= (*data^*q) & m;
64*37da2899SCharles.Forsyth 		if(l > 2)
65*37da2899SCharles.Forsyth 			memmove(q+1, data+1, l-2);
66*37da2899SCharles.Forsyth 		q[l-1] ^= (data[l-1]^q[l-1]) & mr;
67*37da2899SCharles.Forsyth 		q += i->width*sizeof(ulong);
68*37da2899SCharles.Forsyth 		data += l;
69*37da2899SCharles.Forsyth 	}
70*37da2899SCharles.Forsyth 	return ndata;
71*37da2899SCharles.Forsyth }
72