Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "sky.h"
6 static void qtree_expand(Biobuf*, uchar*, int, int, uchar*);
7 static void qtree_copy(uchar*, int, int, uchar*, int);
8 static void qtree_bitins(uchar*, int, int, Pix*, int, int);
9 static void read_bdirect(Biobuf*, Pix*, int, int, int, uchar*, int);
11 void
12 qtree_decode(Biobuf *infile, Pix *a, int n, int nqx, int nqy, int nbitplanes)
13 {
14 int log2n, k, bit, b, nqmax;
15 int nx,ny,nfx,nfy,c;
16 int nqx2, nqy2;
17 unsigned char *scratch;
19 /*
20 * log2n is log2 of max(nqx,nqy) rounded up to next power of 2
21 */
22 nqmax = nqy;
23 if(nqx > nqmax)
24 nqmax = nqx;
25 log2n = log(nqmax)/LN2+0.5;
26 if (nqmax > (1<<log2n))
27 log2n++;
29 /*
30 * allocate scratch array for working space
31 */
32 nqx2 = (nqx+1)/2;
33 nqy2 = (nqy+1)/2;
34 scratch = (uchar*)malloc(nqx2*nqy2);
35 if(scratch == nil) {
36 fprint(2, "qtree_decode: insufficient memory\n");
37 exits("memory");
38 }
40 /*
41 * now decode each bit plane, starting at the top
42 * A is assumed to be initialized to zero
43 */
44 for(bit = nbitplanes-1; bit >= 0; bit--) {
45 /*
46 * Was bitplane was quadtree-coded or written directly?
47 */
48 b = input_nybble(infile);
49 if(b == 0) {
50 /*
51 * bit map was written directly
52 */
53 read_bdirect(infile, a, n, nqx, nqy, scratch, bit);
54 } else
55 if(b != 0xf) {
56 fprint(2, "qtree_decode: bad format code %x\n",b);
57 exits("format");
58 } else {
59 /*
60 * bitmap was quadtree-coded, do log2n expansions
61 * read first code
62 */
64 scratch[0] = input_huffman(infile);
66 /*
67 * do log2n expansions, reading codes from file as necessary
68 */
69 nx = 1;
70 ny = 1;
71 nfx = nqx;
72 nfy = nqy;
73 c = 1<<log2n;
74 for(k = 1; k<log2n; k++) {
75 /*
76 * this somewhat cryptic code generates the sequence
77 * n[k-1] = (n[k]+1)/2 where n[log2n]=nqx or nqy
78 */
79 c = c>>1;
80 nx = nx<<1;
81 ny = ny<<1;
82 if(nfx <= c)
83 nx--;
84 else
85 nfx -= c;
86 if(nfy <= c)
87 ny--;
88 else
89 nfy -= c;
90 qtree_expand(infile, scratch, nx, ny, scratch);
91 }
93 /*
94 * copy last set of 4-bit codes to bitplane bit of array a
95 */
96 qtree_bitins(scratch, nqx, nqy, a, n, bit);
97 }
98 }
99 free(scratch);
102 /*
103 * do one quadtree expansion step on array a[(nqx+1)/2,(nqy+1)/2]
104 * results put into b[nqx,nqy] (which may be the same as a)
105 */
106 static
107 void
108 qtree_expand(Biobuf *infile, uchar *a, int nx, int ny, uchar *b)
110 uchar *b1;
112 /*
113 * first copy a to b, expanding each 4-bit value
114 */
115 qtree_copy(a, nx, ny, b, ny);
117 /*
118 * now read new 4-bit values into b for each non-zero element
119 */
120 b1 = &b[nx*ny];
121 while(b1 > b) {
122 b1--;
123 if(*b1 != 0)
124 *b1 = input_huffman(infile);
128 /*
129 * copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding
130 * each value to 2x2 pixels
131 * a,b may be same array
132 */
133 static
134 void
135 qtree_copy(uchar *a, int nx, int ny, uchar *b, int n)
137 int i, j, k, nx2, ny2;
138 int s00, s10;
140 /*
141 * first copy 4-bit values to b
142 * start at end in case a,b are same array
143 */
144 nx2 = (nx+1)/2;
145 ny2 = (ny+1)/2;
146 k = ny2*(nx2-1) + ny2-1; /* k is index of a[i,j] */
147 for (i = nx2-1; i >= 0; i--) {
148 s00 = 2*(n*i+ny2-1); /* s00 is index of b[2*i,2*j] */
149 for (j = ny2-1; j >= 0; j--) {
150 b[s00] = a[k];
151 k -= 1;
152 s00 -= 2;
156 /*
157 * now expand each 2x2 block
158 */
159 for(i = 0; i<nx-1; i += 2) {
160 s00 = n*i; /* s00 is index of b[i,j] */
161 s10 = s00+n; /* s10 is index of b[i+1,j] */
162 for(j = 0; j<ny-1; j += 2) {
163 b[s10+1] = b[s00] & 1;
164 b[s10 ] = (b[s00]>>1) & 1;
165 b[s00+1] = (b[s00]>>2) & 1;
166 b[s00 ] = (b[s00]>>3) & 1;
167 s00 += 2;
168 s10 += 2;
170 if(j < ny) {
171 /*
172 * row size is odd, do last element in row
173 * s00+1, s10+1 are off edge
174 */
175 b[s10 ] = (b[s00]>>1) & 1;
176 b[s00 ] = (b[s00]>>3) & 1;
179 if(i < nx) {
180 /*
181 * column size is odd, do last row
182 * s10, s10+1 are off edge
183 */
184 s00 = n*i;
185 for (j = 0; j<ny-1; j += 2) {
186 b[s00+1] = (b[s00]>>2) & 1;
187 b[s00 ] = (b[s00]>>3) & 1;
188 s00 += 2;
190 if(j < ny) {
191 /*
192 * both row and column size are odd, do corner element
193 * s00+1, s10, s10+1 are off edge
194 */
195 b[s00 ] = (b[s00]>>3) & 1;
200 /*
201 * Copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding
202 * each value to 2x2 pixels and inserting into bitplane BIT of B.
203 * A,B may NOT be same array (it wouldn't make sense to be inserting
204 * bits into the same array anyway.)
205 */
206 static
207 void
208 qtree_bitins(uchar *a, int nx, int ny, Pix *b, int n, int bit)
210 int i, j;
211 Pix *s00, *s10;
212 Pix px;
214 /*
215 * expand each 2x2 block
216 */
217 for(i=0; i<nx-1; i+=2) {
218 s00 = &b[n*i]; /* s00 is index of b[i,j] */
219 s10 = s00+n; /* s10 is index of b[i+1,j] */
220 for(j=0; j<ny-1; j+=2) {
221 px = *a++;
222 s10[1] |= ( px & 1) << bit;
223 s10[0] |= ((px>>1) & 1) << bit;
224 s00[1] |= ((px>>2) & 1) << bit;
225 s00[0] |= ((px>>3) & 1) << bit;
226 s00 += 2;
227 s10 += 2;
229 if(j < ny) {
230 /*
231 * row size is odd, do last element in row
232 * s00+1, s10+1 are off edge
233 */
234 px = *a++;
235 s10[0] |= ((px>>1) & 1) << bit;
236 s00[0] |= ((px>>3) & 1) << bit;
239 if(i < nx) {
240 /*
241 * column size is odd, do last row
242 * s10, s10+1 are off edge
243 */
244 s00 = &b[n*i];
245 for(j=0; j<ny-1; j+=2) {
246 px = *a++;
247 s00[1] |= ((px>>2) & 1) << bit;
248 s00[0] |= ((px>>3) & 1) << bit;
249 s00 += 2;
251 if(j < ny) {
252 /*
253 * both row and column size are odd, do corner element
254 * s00+1, s10, s10+1 are off edge
255 */
256 s00[0] |= ((*a>>3) & 1) << bit;
261 static
262 void
263 read_bdirect(Biobuf *infile, Pix *a, int n, int nqx, int nqy, uchar *scratch, int bit)
265 int i;
267 /*
268 * read bit image packed 4 pixels/nybble
269 */
270 for(i = 0; i < ((nqx+1)/2) * ((nqy+1)/2); i++) {
271 scratch[i] = input_nybble(infile);
274 /*
275 * insert in bitplane BIT of image A
276 */
277 qtree_bitins(scratch, nqx, nqy, a, n, bit);