Initial revision
This commit is contained in:
parent
ed7c8e8d02
commit
76193d7cb0
223 changed files with 32479 additions and 0 deletions
200
src/libdraw/md-alloc.c
Normal file
200
src/libdraw/md-alloc.c
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <memdraw.h>
|
||||
|
||||
#define poolalloc(a, b) malloc(b)
|
||||
#define poolfree(a, b) free(b)
|
||||
|
||||
void
|
||||
memimagemove(void *from, void *to)
|
||||
{
|
||||
Memdata *md;
|
||||
|
||||
md = *(Memdata**)to;
|
||||
if(md->base != from){
|
||||
print("compacted data not right: #%p\n", md->base);
|
||||
abort();
|
||||
}
|
||||
md->base = to;
|
||||
|
||||
/* if allocmemimage changes this must change too */
|
||||
md->bdata = (uchar*)&md->base[2];
|
||||
}
|
||||
|
||||
Memimage*
|
||||
allocmemimaged(Rectangle r, u32int chan, Memdata *md, void *X)
|
||||
{
|
||||
int d;
|
||||
u32int l;
|
||||
Memimage *i;
|
||||
|
||||
if(Dx(r) <= 0 || Dy(r) <= 0){
|
||||
werrstr("bad rectangle %R", r);
|
||||
return nil;
|
||||
}
|
||||
if((d = chantodepth(chan)) == 0) {
|
||||
werrstr("bad channel descriptor %.8lux", chan);
|
||||
return nil;
|
||||
}
|
||||
|
||||
l = wordsperline(r, d);
|
||||
|
||||
i = mallocz(sizeof(Memimage), 1);
|
||||
if(i == nil)
|
||||
return nil;
|
||||
|
||||
i->X = X;
|
||||
i->data = md;
|
||||
i->zero = sizeof(u32int)*l*r.min.y;
|
||||
|
||||
if(r.min.x >= 0)
|
||||
i->zero += (r.min.x*d)/8;
|
||||
else
|
||||
i->zero -= (-r.min.x*d+7)/8;
|
||||
i->zero = -i->zero;
|
||||
i->width = l;
|
||||
i->r = r;
|
||||
i->clipr = r;
|
||||
i->flags = 0;
|
||||
i->layer = nil;
|
||||
i->cmap = memdefcmap;
|
||||
if(memsetchan(i, chan) < 0){
|
||||
free(i);
|
||||
return nil;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
Memimage*
|
||||
_allocmemimage(Rectangle r, u32int chan)
|
||||
{
|
||||
int d;
|
||||
u32int l, nw;
|
||||
Memdata *md;
|
||||
Memimage *i;
|
||||
|
||||
if((d = chantodepth(chan)) == 0) {
|
||||
werrstr("bad channel descriptor %.8lux", chan);
|
||||
return nil;
|
||||
}
|
||||
|
||||
l = wordsperline(r, d);
|
||||
nw = l*Dy(r);
|
||||
md = malloc(sizeof(Memdata));
|
||||
if(md == nil)
|
||||
return nil;
|
||||
|
||||
md->ref = 1;
|
||||
md->base = poolalloc(imagmem, (2+nw)*sizeof(u32int));
|
||||
if(md->base == nil){
|
||||
free(md);
|
||||
return nil;
|
||||
}
|
||||
|
||||
md->base[0] = (u32int)md;
|
||||
md->base[1] = getcallerpc(&r);
|
||||
|
||||
/* if this changes, memimagemove must change too */
|
||||
md->bdata = (uchar*)&md->base[2];
|
||||
|
||||
md->allocd = 1;
|
||||
|
||||
i = allocmemimaged(r, chan, md, nil);
|
||||
if(i == nil){
|
||||
poolfree(imagmem, md->base);
|
||||
free(md);
|
||||
return nil;
|
||||
}
|
||||
md->imref = i;
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
_freememimage(Memimage *i)
|
||||
{
|
||||
if(i == nil)
|
||||
return;
|
||||
if(i->data->ref-- == 1 && i->data->allocd){
|
||||
if(i->data->base)
|
||||
poolfree(imagmem, i->data->base);
|
||||
free(i->data);
|
||||
}
|
||||
free(i);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wordaddr is deprecated.
|
||||
*/
|
||||
u32int*
|
||||
wordaddr(Memimage *i, Point p)
|
||||
{
|
||||
return (u32int*) ((u32int)byteaddr(i, p) & ~(sizeof(u32int)-1));
|
||||
}
|
||||
|
||||
uchar*
|
||||
byteaddr(Memimage *i, Point p)
|
||||
{
|
||||
uchar *a;
|
||||
|
||||
a = i->data->bdata+i->zero+sizeof(u32int)*p.y*i->width;
|
||||
|
||||
if(i->depth < 8){
|
||||
/*
|
||||
* We need to always round down,
|
||||
* but C rounds toward zero.
|
||||
*/
|
||||
int np;
|
||||
np = 8/i->depth;
|
||||
if(p.x < 0)
|
||||
return a+(p.x-np+1)/np;
|
||||
else
|
||||
return a+p.x/np;
|
||||
}
|
||||
else
|
||||
return a+p.x*(i->depth/8);
|
||||
}
|
||||
|
||||
int
|
||||
memsetchan(Memimage *i, u32int chan)
|
||||
{
|
||||
int d;
|
||||
int t, j, k;
|
||||
u32int cc;
|
||||
int bytes;
|
||||
|
||||
if((d = chantodepth(chan)) == 0) {
|
||||
werrstr("bad channel descriptor");
|
||||
return -1;
|
||||
}
|
||||
|
||||
i->depth = d;
|
||||
i->chan = chan;
|
||||
i->flags &= ~(Fgrey|Falpha|Fcmap|Fbytes);
|
||||
bytes = 1;
|
||||
for(cc=chan, j=0, k=0; cc; j+=NBITS(cc), cc>>=8, k++){
|
||||
t=TYPE(cc);
|
||||
if(t < 0 || t >= NChan){
|
||||
werrstr("bad channel string");
|
||||
return -1;
|
||||
}
|
||||
if(t == CGrey)
|
||||
i->flags |= Fgrey;
|
||||
if(t == CAlpha)
|
||||
i->flags |= Falpha;
|
||||
if(t == CMap && i->cmap == nil){
|
||||
i->cmap = memdefcmap;
|
||||
i->flags |= Fcmap;
|
||||
}
|
||||
|
||||
i->shift[t] = j;
|
||||
i->mask[t] = (1<<NBITS(cc))-1;
|
||||
i->nbits[t] = NBITS(cc);
|
||||
if(NBITS(cc) != 8)
|
||||
bytes = 0;
|
||||
}
|
||||
i->nchan = k;
|
||||
if(bytes)
|
||||
i->flags |= Fbytes;
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue