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