1*7dd7cddfSDavid du Colombier #include "../lib9.h" 2*7dd7cddfSDavid du Colombier 3*7dd7cddfSDavid du Colombier #include "../libdraw/draw.h" 4*7dd7cddfSDavid du Colombier #include "../libmemdraw/memdraw.h" 5*7dd7cddfSDavid du Colombier 6*7dd7cddfSDavid du Colombier void 7*7dd7cddfSDavid du Colombier memimagemove(void *from, void *to) 8*7dd7cddfSDavid du Colombier { 9*7dd7cddfSDavid du Colombier Memdata *md; 10*7dd7cddfSDavid du Colombier 11*7dd7cddfSDavid du Colombier md = *(Memdata**)to; 12*7dd7cddfSDavid du Colombier if(md->base != from){ 13*7dd7cddfSDavid du Colombier print("compacted data not right: #%p\n", md->base); 14*7dd7cddfSDavid du Colombier abort(); 15*7dd7cddfSDavid du Colombier } 16*7dd7cddfSDavid du Colombier md->base = to; 17*7dd7cddfSDavid du Colombier 18*7dd7cddfSDavid du Colombier /* if allocmemimage changes this must change too */ 19*7dd7cddfSDavid du Colombier md->bdata = (uchar*)&md->base[2]; 20*7dd7cddfSDavid du Colombier } 21*7dd7cddfSDavid du Colombier 22*7dd7cddfSDavid du Colombier Memimage* 23*7dd7cddfSDavid du Colombier allocmemimaged(Rectangle r, ulong chan, Memdata *md, void *X) 24*7dd7cddfSDavid du Colombier { 25*7dd7cddfSDavid du Colombier int d; 26*7dd7cddfSDavid du Colombier ulong l; 27*7dd7cddfSDavid du Colombier Memimage *i; 28*7dd7cddfSDavid du Colombier 29*7dd7cddfSDavid du Colombier if((d = chantodepth(chan)) == 0) { 30*7dd7cddfSDavid du Colombier werrstr("bad channel descriptor %.8lux", chan); 31*7dd7cddfSDavid du Colombier return nil; 32*7dd7cddfSDavid du Colombier } 33*7dd7cddfSDavid du Colombier 34*7dd7cddfSDavid du Colombier l = wordsperline(r, d); 35*7dd7cddfSDavid du Colombier 36*7dd7cddfSDavid du Colombier i = mallocz(sizeof(Memimage)); 37*7dd7cddfSDavid du Colombier if(i == nil) 38*7dd7cddfSDavid du Colombier return nil; 39*7dd7cddfSDavid du Colombier 40*7dd7cddfSDavid du Colombier i->data = md; 41*7dd7cddfSDavid du Colombier i->zero = sizeof(ulong)*l*r.min.y; 42*7dd7cddfSDavid du Colombier 43*7dd7cddfSDavid du Colombier if(r.min.x >= 0) 44*7dd7cddfSDavid du Colombier i->zero += (r.min.x*d)/8; 45*7dd7cddfSDavid du Colombier else 46*7dd7cddfSDavid du Colombier i->zero -= (-r.min.x*d+7)/8; 47*7dd7cddfSDavid du Colombier i->zero = -i->zero; 48*7dd7cddfSDavid du Colombier i->width = l; 49*7dd7cddfSDavid du Colombier i->r = r; 50*7dd7cddfSDavid du Colombier i->clipr = r; 51*7dd7cddfSDavid du Colombier i->flags = 0; 52*7dd7cddfSDavid du Colombier i->layer = nil; 53*7dd7cddfSDavid du Colombier i->cmap = memdefcmap; 54*7dd7cddfSDavid du Colombier if(memsetchan(i, chan) < 0){ 55*7dd7cddfSDavid du Colombier free(i); 56*7dd7cddfSDavid du Colombier return nil; 57*7dd7cddfSDavid du Colombier } 58*7dd7cddfSDavid du Colombier i->X = X; 59*7dd7cddfSDavid du Colombier return i; 60*7dd7cddfSDavid du Colombier } 61*7dd7cddfSDavid du Colombier 62*7dd7cddfSDavid du Colombier Memimage* 63*7dd7cddfSDavid du Colombier _allocmemimage(Rectangle r, ulong chan) 64*7dd7cddfSDavid du Colombier { 65*7dd7cddfSDavid du Colombier int d; 66*7dd7cddfSDavid du Colombier ulong l, nw; 67*7dd7cddfSDavid du Colombier Memdata *md; 68*7dd7cddfSDavid du Colombier Memimage *i; 69*7dd7cddfSDavid du Colombier 70*7dd7cddfSDavid du Colombier if((d = chantodepth(chan)) == 0) { 71*7dd7cddfSDavid du Colombier werrstr("bad channel descriptor %.8lux", chan); 72*7dd7cddfSDavid du Colombier return nil; 73*7dd7cddfSDavid du Colombier } 74*7dd7cddfSDavid du Colombier 75*7dd7cddfSDavid du Colombier l = wordsperline(r, d); 76*7dd7cddfSDavid du Colombier nw = l*Dy(r); 77*7dd7cddfSDavid du Colombier md = malloc(sizeof(Memdata)); 78*7dd7cddfSDavid du Colombier if(md == nil) 79*7dd7cddfSDavid du Colombier return nil; 80*7dd7cddfSDavid du Colombier 81*7dd7cddfSDavid du Colombier md->ref = 1; 82*7dd7cddfSDavid du Colombier md->base = mallocz((2+nw)*sizeof(ulong)); 83*7dd7cddfSDavid du Colombier if(md->base == nil){ 84*7dd7cddfSDavid du Colombier free(md); 85*7dd7cddfSDavid du Colombier return nil; 86*7dd7cddfSDavid du Colombier } 87*7dd7cddfSDavid du Colombier 88*7dd7cddfSDavid du Colombier md->base[0] = (ulong)md; 89*7dd7cddfSDavid du Colombier md->base[1] = getcallerpc(&r); 90*7dd7cddfSDavid du Colombier 91*7dd7cddfSDavid du Colombier /* if this changes, memimagemove must change too */ 92*7dd7cddfSDavid du Colombier md->bdata = (uchar*)&md->base[2]; 93*7dd7cddfSDavid du Colombier 94*7dd7cddfSDavid du Colombier md->allocd = 1; 95*7dd7cddfSDavid du Colombier 96*7dd7cddfSDavid du Colombier i = allocmemimaged(r, chan, md, nil); 97*7dd7cddfSDavid du Colombier if(i == nil){ 98*7dd7cddfSDavid du Colombier free(md); 99*7dd7cddfSDavid du Colombier return nil; 100*7dd7cddfSDavid du Colombier } 101*7dd7cddfSDavid du Colombier md->imref = i; 102*7dd7cddfSDavid du Colombier return i; 103*7dd7cddfSDavid du Colombier } 104*7dd7cddfSDavid du Colombier 105*7dd7cddfSDavid du Colombier void 106*7dd7cddfSDavid du Colombier _freememimage(Memimage *i) 107*7dd7cddfSDavid du Colombier { 108*7dd7cddfSDavid du Colombier if(i == nil) 109*7dd7cddfSDavid du Colombier return; 110*7dd7cddfSDavid du Colombier if(i->data->ref-- == 1 && i->data->allocd){ 111*7dd7cddfSDavid du Colombier if(i->data->base) 112*7dd7cddfSDavid du Colombier free(i->data->base); 113*7dd7cddfSDavid du Colombier free(i->data); 114*7dd7cddfSDavid du Colombier } 115*7dd7cddfSDavid du Colombier free(i); 116*7dd7cddfSDavid du Colombier } 117*7dd7cddfSDavid du Colombier 118*7dd7cddfSDavid du Colombier /* 119*7dd7cddfSDavid du Colombier * Wordaddr is deprecated. 120*7dd7cddfSDavid du Colombier */ 121*7dd7cddfSDavid du Colombier ulong* 122*7dd7cddfSDavid du Colombier wordaddr(Memimage *i, Point p) 123*7dd7cddfSDavid du Colombier { 124*7dd7cddfSDavid du Colombier return (ulong*) ((ulong)byteaddr(i, p) & ~(sizeof(ulong)-1)); 125*7dd7cddfSDavid du Colombier } 126*7dd7cddfSDavid du Colombier 127*7dd7cddfSDavid du Colombier uchar* 128*7dd7cddfSDavid du Colombier byteaddr(Memimage *i, Point p) 129*7dd7cddfSDavid du Colombier { 130*7dd7cddfSDavid du Colombier uchar *a; 131*7dd7cddfSDavid du Colombier 132*7dd7cddfSDavid du Colombier a = i->data->bdata+i->zero+sizeof(ulong)*p.y*i->width; 133*7dd7cddfSDavid du Colombier 134*7dd7cddfSDavid du Colombier if(i->depth < 8){ 135*7dd7cddfSDavid du Colombier /* 136*7dd7cddfSDavid du Colombier * We need to always round down, 137*7dd7cddfSDavid du Colombier * but C rounds toward zero. 138*7dd7cddfSDavid du Colombier */ 139*7dd7cddfSDavid du Colombier int np; 140*7dd7cddfSDavid du Colombier np = 8/i->depth; 141*7dd7cddfSDavid du Colombier if(p.x < 0) 142*7dd7cddfSDavid du Colombier return a+(p.x-np+1)/np; 143*7dd7cddfSDavid du Colombier else 144*7dd7cddfSDavid du Colombier return a+p.x/np; 145*7dd7cddfSDavid du Colombier } 146*7dd7cddfSDavid du Colombier else 147*7dd7cddfSDavid du Colombier return a+p.x*(i->depth/8); 148*7dd7cddfSDavid du Colombier } 149*7dd7cddfSDavid du Colombier 150*7dd7cddfSDavid du Colombier void 151*7dd7cddfSDavid du Colombier _memfillcolor(Memimage *i, ulong val) 152*7dd7cddfSDavid du Colombier { 153*7dd7cddfSDavid du Colombier static Memimage *paint; 154*7dd7cddfSDavid du Colombier uchar *data; 155*7dd7cddfSDavid du Colombier 156*7dd7cddfSDavid du Colombier if(paint == nil){ 157*7dd7cddfSDavid du Colombier paint = allocmemimage(Rect(0,0,1,1), ARGB32); 158*7dd7cddfSDavid du Colombier if(paint == nil) 159*7dd7cddfSDavid du Colombier return; 160*7dd7cddfSDavid du Colombier paint->clipr = Rect(-0x3FFFFFF,-0x3FFFFFF,0x3FFFFFF,0x3FFFFFF); 161*7dd7cddfSDavid du Colombier paint->flags |= Frepl; 162*7dd7cddfSDavid du Colombier } 163*7dd7cddfSDavid du Colombier 164*7dd7cddfSDavid du Colombier data = byteaddr(paint, Pt(0,0)); 165*7dd7cddfSDavid du Colombier data[0] = val>>8; /* blue */ 166*7dd7cddfSDavid du Colombier data[1] = val>>16; /* green */ 167*7dd7cddfSDavid du Colombier data[2] = val>>24; /* red */ 168*7dd7cddfSDavid du Colombier data[3] = val; /* alpha */ 169*7dd7cddfSDavid du Colombier 170*7dd7cddfSDavid du Colombier memimagedraw(i, i->r, paint, ZP, nil, ZP); 171*7dd7cddfSDavid du Colombier } 172*7dd7cddfSDavid du Colombier 173*7dd7cddfSDavid du Colombier int 174*7dd7cddfSDavid du Colombier memsetchan(Memimage *i, ulong chan) 175*7dd7cddfSDavid du Colombier { 176*7dd7cddfSDavid du Colombier int d; 177*7dd7cddfSDavid du Colombier int t, j, k; 178*7dd7cddfSDavid du Colombier ulong cc; 179*7dd7cddfSDavid du Colombier int bytes; 180*7dd7cddfSDavid du Colombier 181*7dd7cddfSDavid du Colombier assert(i->X == nil); 182*7dd7cddfSDavid du Colombier if((d = chantodepth(chan)) == 0) { 183*7dd7cddfSDavid du Colombier werrstr("bad channel descriptor"); 184*7dd7cddfSDavid du Colombier return -1; 185*7dd7cddfSDavid du Colombier } 186*7dd7cddfSDavid du Colombier 187*7dd7cddfSDavid du Colombier i->depth = d; 188*7dd7cddfSDavid du Colombier i->chan = chan; 189*7dd7cddfSDavid du Colombier i->flags &= ~(Fgrey|Falpha|Fcmap|Fbytes); 190*7dd7cddfSDavid du Colombier bytes = 1; 191*7dd7cddfSDavid du Colombier for(cc=chan, j=0, k=0; cc; j+=NBITS(cc), cc>>=8, k++){ 192*7dd7cddfSDavid du Colombier t=TYPE(cc); 193*7dd7cddfSDavid du Colombier if(t < 0 || t >= NChan){ 194*7dd7cddfSDavid du Colombier werrstr("bad channel string"); 195*7dd7cddfSDavid du Colombier return -1; 196*7dd7cddfSDavid du Colombier } 197*7dd7cddfSDavid du Colombier if(t == CGrey) 198*7dd7cddfSDavid du Colombier i->flags |= Fgrey; 199*7dd7cddfSDavid du Colombier if(t == CAlpha) 200*7dd7cddfSDavid du Colombier i->flags |= Falpha; 201*7dd7cddfSDavid du Colombier if(t == CMap && i->cmap == nil){ 202*7dd7cddfSDavid du Colombier i->cmap = memdefcmap; 203*7dd7cddfSDavid du Colombier i->flags |= Fcmap; 204*7dd7cddfSDavid du Colombier } 205*7dd7cddfSDavid du Colombier 206*7dd7cddfSDavid du Colombier i->shift[t] = j; 207*7dd7cddfSDavid du Colombier i->mask[t] = (1<<NBITS(cc))-1; 208*7dd7cddfSDavid du Colombier i->nbits[t] = NBITS(cc); 209*7dd7cddfSDavid du Colombier if(NBITS(cc) != 8) 210*7dd7cddfSDavid du Colombier bytes = 0; 211*7dd7cddfSDavid du Colombier } 212*7dd7cddfSDavid du Colombier i->nchan = k; 213*7dd7cddfSDavid du Colombier if(bytes) 214*7dd7cddfSDavid du Colombier i->flags |= Fbytes; 215*7dd7cddfSDavid du Colombier return 0; 216*7dd7cddfSDavid du Colombier } 217