Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	<u.h>
2
#include	<libc.h>
3
#include	<bio.h>
4
#include	"sky.h"
5
 
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);
10
 
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;
18
 
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++;
28
 
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
	}
39
 
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
			 */
63
 
64
			scratch[0] = input_huffman(infile);
65
 
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
			}
92
 
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);
100
}
101
 
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)
109
{
110
	uchar *b1;
111
 
112
	/*
113
	 * first copy a to b, expanding each 4-bit value
114
	 */
115
	qtree_copy(a, nx, ny, b, ny);
116
 
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);
125
	}
126
}
127
 
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)
136
{
137
	int i, j, k, nx2, ny2;
138
	int s00, s10;
139
 
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;
153
		}
154
	}
155
 
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;
169
		}
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;
177
		}
178
	}
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;
189
		}
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;
196
		}
197
	}
198
}
199
 
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)
209
{
210
	int i, j;
211
	Pix *s00, *s10;
212
	Pix px;
213
 
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;
228
		}
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;
237
		}
238
	}
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;
250
		}
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;
257
		}
258
	}
259
}
260
 
261
static
262
void
263
read_bdirect(Biobuf *infile, Pix *a, int n, int nqx, int nqy, uchar *scratch, int bit)
264
{
265
	int i;
266
 
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);
272
	}
273
 
274
	/*
275
	 * insert in bitplane BIT of image A
276
	 */
277
	qtree_bitins(scratch, nqx, nqy, a, n, bit);
278
}