Blame


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