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