Blame


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