Blame


1 8a3b2ceb 2004-04-24 devnull #include <u.h>
2 8a3b2ceb 2004-04-24 devnull #include <libc.h>
3 8a3b2ceb 2004-04-24 devnull #include <bio.h>
4 8a3b2ceb 2004-04-24 devnull #include "sky.h"
5 8a3b2ceb 2004-04-24 devnull
6 8a3b2ceb 2004-04-24 devnull static void unshuffle(Pix*, int, int, Pix*);
7 8a3b2ceb 2004-04-24 devnull static void unshuffle1(Pix*, int, Pix*);
8 8a3b2ceb 2004-04-24 devnull
9 8a3b2ceb 2004-04-24 devnull void
10 8a3b2ceb 2004-04-24 devnull hinv(Pix *a, int nx, int ny)
11 8a3b2ceb 2004-04-24 devnull {
12 8a3b2ceb 2004-04-24 devnull int nmax, log2n, h0, hx, hy, hc, i, j, k;
13 8a3b2ceb 2004-04-24 devnull int nxtop, nytop, nxf, nyf, c;
14 8a3b2ceb 2004-04-24 devnull int oddx, oddy;
15 8a3b2ceb 2004-04-24 devnull int shift;
16 8a3b2ceb 2004-04-24 devnull int s10, s00;
17 8a3b2ceb 2004-04-24 devnull Pix *tmp;
18 8a3b2ceb 2004-04-24 devnull
19 8a3b2ceb 2004-04-24 devnull /*
20 8a3b2ceb 2004-04-24 devnull * log2n is log2 of max(nx, ny) rounded up to next power of 2
21 8a3b2ceb 2004-04-24 devnull */
22 8a3b2ceb 2004-04-24 devnull nmax = ny;
23 8a3b2ceb 2004-04-24 devnull if(nx > nmax)
24 8a3b2ceb 2004-04-24 devnull nmax = nx;
25 8a3b2ceb 2004-04-24 devnull log2n = log(nmax)/LN2 + 0.5;
26 8a3b2ceb 2004-04-24 devnull if(nmax > (1<<log2n))
27 8a3b2ceb 2004-04-24 devnull log2n++;
28 8a3b2ceb 2004-04-24 devnull
29 8a3b2ceb 2004-04-24 devnull /*
30 8a3b2ceb 2004-04-24 devnull * get temporary storage for shuffling elements
31 8a3b2ceb 2004-04-24 devnull */
32 8a3b2ceb 2004-04-24 devnull tmp = (Pix*)malloc(((nmax+1)/2) * sizeof(*tmp));
33 8a3b2ceb 2004-04-24 devnull if(tmp == nil) {
34 8a3b2ceb 2004-04-24 devnull fprint(2, "hinv: insufficient memory\n");
35 8a3b2ceb 2004-04-24 devnull exits("memory");
36 8a3b2ceb 2004-04-24 devnull }
37 8a3b2ceb 2004-04-24 devnull
38 8a3b2ceb 2004-04-24 devnull /*
39 8a3b2ceb 2004-04-24 devnull * do log2n expansions
40 8a3b2ceb 2004-04-24 devnull *
41 8a3b2ceb 2004-04-24 devnull * We're indexing a as a 2-D array with dimensions (nx,ny).
42 8a3b2ceb 2004-04-24 devnull */
43 8a3b2ceb 2004-04-24 devnull shift = 1;
44 8a3b2ceb 2004-04-24 devnull nxtop = 1;
45 8a3b2ceb 2004-04-24 devnull nytop = 1;
46 8a3b2ceb 2004-04-24 devnull nxf = nx;
47 8a3b2ceb 2004-04-24 devnull nyf = ny;
48 8a3b2ceb 2004-04-24 devnull c = 1<<log2n;
49 8a3b2ceb 2004-04-24 devnull for(k = log2n-1; k>=0; k--) {
50 8a3b2ceb 2004-04-24 devnull /*
51 8a3b2ceb 2004-04-24 devnull * this somewhat cryptic code generates the sequence
52 8a3b2ceb 2004-04-24 devnull * ntop[k-1] = (ntop[k]+1)/2, where ntop[log2n] = n
53 8a3b2ceb 2004-04-24 devnull */
54 8a3b2ceb 2004-04-24 devnull c = c>>1;
55 8a3b2ceb 2004-04-24 devnull nxtop = nxtop<<1;
56 8a3b2ceb 2004-04-24 devnull nytop = nytop<<1;
57 8a3b2ceb 2004-04-24 devnull if(nxf <= c)
58 8a3b2ceb 2004-04-24 devnull nxtop--;
59 8a3b2ceb 2004-04-24 devnull else
60 8a3b2ceb 2004-04-24 devnull nxf -= c;
61 8a3b2ceb 2004-04-24 devnull if(nyf <= c)
62 8a3b2ceb 2004-04-24 devnull nytop--;
63 8a3b2ceb 2004-04-24 devnull else
64 8a3b2ceb 2004-04-24 devnull nyf -= c;
65 8a3b2ceb 2004-04-24 devnull
66 8a3b2ceb 2004-04-24 devnull /*
67 8a3b2ceb 2004-04-24 devnull * halve divisors on last pass
68 8a3b2ceb 2004-04-24 devnull */
69 8a3b2ceb 2004-04-24 devnull if(k == 0)
70 8a3b2ceb 2004-04-24 devnull shift = 0;
71 8a3b2ceb 2004-04-24 devnull
72 8a3b2ceb 2004-04-24 devnull /*
73 8a3b2ceb 2004-04-24 devnull * unshuffle in each dimension to interleave coefficients
74 8a3b2ceb 2004-04-24 devnull */
75 8a3b2ceb 2004-04-24 devnull for(i = 0; i<nxtop; i++)
76 8a3b2ceb 2004-04-24 devnull unshuffle1(&a[ny*i], nytop, tmp);
77 8a3b2ceb 2004-04-24 devnull for(j = 0; j<nytop; j++)
78 8a3b2ceb 2004-04-24 devnull unshuffle(&a[j], nxtop, ny, tmp);
79 8a3b2ceb 2004-04-24 devnull oddx = nxtop & 1;
80 8a3b2ceb 2004-04-24 devnull oddy = nytop & 1;
81 8a3b2ceb 2004-04-24 devnull for(i = 0; i<nxtop-oddx; i += 2) {
82 8a3b2ceb 2004-04-24 devnull s00 = ny*i; /* s00 is index of a[i,j] */
83 8a3b2ceb 2004-04-24 devnull s10 = s00+ny; /* s10 is index of a[i+1,j] */
84 8a3b2ceb 2004-04-24 devnull for(j = 0; j<nytop-oddy; j += 2) {
85 8a3b2ceb 2004-04-24 devnull /*
86 8a3b2ceb 2004-04-24 devnull * Multiply h0,hx,hy,hc by 2 (1 the last time through).
87 8a3b2ceb 2004-04-24 devnull */
88 8a3b2ceb 2004-04-24 devnull h0 = a[s00 ] << shift;
89 8a3b2ceb 2004-04-24 devnull hx = a[s10 ] << shift;
90 8a3b2ceb 2004-04-24 devnull hy = a[s00+1] << shift;
91 8a3b2ceb 2004-04-24 devnull hc = a[s10+1] << shift;
92 8a3b2ceb 2004-04-24 devnull
93 8a3b2ceb 2004-04-24 devnull /*
94 8a3b2ceb 2004-04-24 devnull * Divide sums by 4 (shift right 2 bits).
95 8a3b2ceb 2004-04-24 devnull * Add 1 to round -- note that these values are always
96 8a3b2ceb 2004-04-24 devnull * positive so we don't need to do anything special
97 8a3b2ceb 2004-04-24 devnull * for rounding negative numbers.
98 8a3b2ceb 2004-04-24 devnull */
99 8a3b2ceb 2004-04-24 devnull a[s10+1] = (h0 + hx + hy + hc + 2) >> 2;
100 8a3b2ceb 2004-04-24 devnull a[s10 ] = (h0 + hx - hy - hc + 2) >> 2;
101 8a3b2ceb 2004-04-24 devnull a[s00+1] = (h0 - hx + hy - hc + 2) >> 2;
102 8a3b2ceb 2004-04-24 devnull a[s00 ] = (h0 - hx - hy + hc + 2) >> 2;
103 8a3b2ceb 2004-04-24 devnull s00 += 2;
104 8a3b2ceb 2004-04-24 devnull s10 += 2;
105 8a3b2ceb 2004-04-24 devnull }
106 8a3b2ceb 2004-04-24 devnull if(oddy) {
107 8a3b2ceb 2004-04-24 devnull /*
108 8a3b2ceb 2004-04-24 devnull * do last element in row if row length is odd
109 8a3b2ceb 2004-04-24 devnull * s00+1, s10+1 are off edge
110 8a3b2ceb 2004-04-24 devnull */
111 8a3b2ceb 2004-04-24 devnull h0 = a[s00 ] << shift;
112 8a3b2ceb 2004-04-24 devnull hx = a[s10 ] << shift;
113 8a3b2ceb 2004-04-24 devnull a[s10 ] = (h0 + hx + 2) >> 2;
114 8a3b2ceb 2004-04-24 devnull a[s00 ] = (h0 - hx + 2) >> 2;
115 8a3b2ceb 2004-04-24 devnull }
116 8a3b2ceb 2004-04-24 devnull }
117 8a3b2ceb 2004-04-24 devnull if(oddx) {
118 8a3b2ceb 2004-04-24 devnull /*
119 8a3b2ceb 2004-04-24 devnull * do last row if column length is odd
120 8a3b2ceb 2004-04-24 devnull * s10, s10+1 are off edge
121 8a3b2ceb 2004-04-24 devnull */
122 8a3b2ceb 2004-04-24 devnull s00 = ny*i;
123 8a3b2ceb 2004-04-24 devnull for(j = 0; j<nytop-oddy; j += 2) {
124 8a3b2ceb 2004-04-24 devnull h0 = a[s00 ] << shift;
125 8a3b2ceb 2004-04-24 devnull hy = a[s00+1] << shift;
126 8a3b2ceb 2004-04-24 devnull a[s00+1] = (h0 + hy + 2) >> 2;
127 8a3b2ceb 2004-04-24 devnull a[s00 ] = (h0 - hy + 2) >> 2;
128 8a3b2ceb 2004-04-24 devnull s00 += 2;
129 8a3b2ceb 2004-04-24 devnull }
130 8a3b2ceb 2004-04-24 devnull if(oddy) {
131 8a3b2ceb 2004-04-24 devnull /*
132 8a3b2ceb 2004-04-24 devnull * do corner element if both row and column lengths are odd
133 8a3b2ceb 2004-04-24 devnull * s00+1, s10, s10+1 are off edge
134 8a3b2ceb 2004-04-24 devnull */
135 8a3b2ceb 2004-04-24 devnull h0 = a[s00 ] << shift;
136 8a3b2ceb 2004-04-24 devnull a[s00 ] = (h0 + 2) >> 2;
137 8a3b2ceb 2004-04-24 devnull }
138 8a3b2ceb 2004-04-24 devnull }
139 8a3b2ceb 2004-04-24 devnull }
140 8a3b2ceb 2004-04-24 devnull free(tmp);
141 8a3b2ceb 2004-04-24 devnull }
142 8a3b2ceb 2004-04-24 devnull
143 8a3b2ceb 2004-04-24 devnull static
144 8a3b2ceb 2004-04-24 devnull void
145 8a3b2ceb 2004-04-24 devnull unshuffle(Pix *a, int n, int n2, Pix *tmp)
146 8a3b2ceb 2004-04-24 devnull {
147 8a3b2ceb 2004-04-24 devnull int i;
148 8a3b2ceb 2004-04-24 devnull int nhalf, twon2, n2xnhalf;
149 8a3b2ceb 2004-04-24 devnull Pix *p1, *p2, *pt;
150 8a3b2ceb 2004-04-24 devnull
151 8a3b2ceb 2004-04-24 devnull twon2 = n2<<1;
152 8a3b2ceb 2004-04-24 devnull nhalf = (n+1)>>1;
153 8a3b2ceb 2004-04-24 devnull n2xnhalf = n2*nhalf; /* pointer to a[i] */
154 8a3b2ceb 2004-04-24 devnull
155 8a3b2ceb 2004-04-24 devnull /*
156 8a3b2ceb 2004-04-24 devnull * copy 2nd half of array to tmp
157 8a3b2ceb 2004-04-24 devnull */
158 8a3b2ceb 2004-04-24 devnull pt = tmp;
159 8a3b2ceb 2004-04-24 devnull p1 = &a[n2xnhalf]; /* pointer to a[i] */
160 8a3b2ceb 2004-04-24 devnull for(i=nhalf; i<n; i++) {
161 8a3b2ceb 2004-04-24 devnull *pt = *p1;
162 8a3b2ceb 2004-04-24 devnull pt++;
163 8a3b2ceb 2004-04-24 devnull p1 += n2;
164 8a3b2ceb 2004-04-24 devnull }
165 8a3b2ceb 2004-04-24 devnull
166 8a3b2ceb 2004-04-24 devnull /*
167 8a3b2ceb 2004-04-24 devnull * distribute 1st half of array to even elements
168 8a3b2ceb 2004-04-24 devnull */
169 8a3b2ceb 2004-04-24 devnull p2 = &a[n2xnhalf]; /* pointer to a[i] */
170 8a3b2ceb 2004-04-24 devnull p1 = &a[n2xnhalf<<1]; /* pointer to a[2*i] */
171 8a3b2ceb 2004-04-24 devnull for(i=nhalf-1; i>=0; i--) {
172 8a3b2ceb 2004-04-24 devnull p1 -= twon2;
173 8a3b2ceb 2004-04-24 devnull p2 -= n2;
174 8a3b2ceb 2004-04-24 devnull *p1 = *p2;
175 8a3b2ceb 2004-04-24 devnull }
176 8a3b2ceb 2004-04-24 devnull
177 8a3b2ceb 2004-04-24 devnull /*
178 8a3b2ceb 2004-04-24 devnull * now distribute 2nd half of array (in tmp) to odd elements
179 8a3b2ceb 2004-04-24 devnull */
180 8a3b2ceb 2004-04-24 devnull pt = tmp;
181 8a3b2ceb 2004-04-24 devnull p1 = &a[n2]; /* pointer to a[i] */
182 8a3b2ceb 2004-04-24 devnull for(i=1; i<n; i+=2) {
183 8a3b2ceb 2004-04-24 devnull *p1 = *pt;
184 8a3b2ceb 2004-04-24 devnull p1 += twon2;
185 8a3b2ceb 2004-04-24 devnull pt++;
186 8a3b2ceb 2004-04-24 devnull }
187 8a3b2ceb 2004-04-24 devnull }
188 8a3b2ceb 2004-04-24 devnull
189 8a3b2ceb 2004-04-24 devnull static
190 8a3b2ceb 2004-04-24 devnull void
191 8a3b2ceb 2004-04-24 devnull unshuffle1(Pix *a, int n, Pix *tmp)
192 8a3b2ceb 2004-04-24 devnull {
193 8a3b2ceb 2004-04-24 devnull int i;
194 8a3b2ceb 2004-04-24 devnull int nhalf;
195 8a3b2ceb 2004-04-24 devnull Pix *p1, *p2, *pt;
196 8a3b2ceb 2004-04-24 devnull
197 8a3b2ceb 2004-04-24 devnull nhalf = (n+1) >> 1;
198 8a3b2ceb 2004-04-24 devnull
199 8a3b2ceb 2004-04-24 devnull /*
200 8a3b2ceb 2004-04-24 devnull * copy 2nd half of array to tmp
201 8a3b2ceb 2004-04-24 devnull */
202 8a3b2ceb 2004-04-24 devnull pt = tmp;
203 8a3b2ceb 2004-04-24 devnull p1 = &a[nhalf]; /* pointer to a[i] */
204 8a3b2ceb 2004-04-24 devnull for(i=nhalf; i<n; i++) {
205 8a3b2ceb 2004-04-24 devnull *pt = *p1;
206 8a3b2ceb 2004-04-24 devnull pt++;
207 8a3b2ceb 2004-04-24 devnull p1++;
208 8a3b2ceb 2004-04-24 devnull }
209 8a3b2ceb 2004-04-24 devnull
210 8a3b2ceb 2004-04-24 devnull /*
211 8a3b2ceb 2004-04-24 devnull * distribute 1st half of array to even elements
212 8a3b2ceb 2004-04-24 devnull */
213 8a3b2ceb 2004-04-24 devnull p2 = &a[nhalf]; /* pointer to a[i] */
214 8a3b2ceb 2004-04-24 devnull p1 = &a[nhalf<<1]; /* pointer to a[2*i] */
215 8a3b2ceb 2004-04-24 devnull for(i=nhalf-1; i>=0; i--) {
216 8a3b2ceb 2004-04-24 devnull p1 -= 2;
217 8a3b2ceb 2004-04-24 devnull p2--;
218 8a3b2ceb 2004-04-24 devnull *p1 = *p2;
219 8a3b2ceb 2004-04-24 devnull }
220 8a3b2ceb 2004-04-24 devnull
221 8a3b2ceb 2004-04-24 devnull /*
222 8a3b2ceb 2004-04-24 devnull * now distribute 2nd half of array (in tmp) to odd elements
223 8a3b2ceb 2004-04-24 devnull */
224 8a3b2ceb 2004-04-24 devnull pt = tmp;
225 8a3b2ceb 2004-04-24 devnull p1 = &a[1]; /* pointer to a[i] */
226 8a3b2ceb 2004-04-24 devnull for(i=1; i<n; i+=2) {
227 8a3b2ceb 2004-04-24 devnull *p1 = *pt;
228 8a3b2ceb 2004-04-24 devnull p1 += 2;
229 8a3b2ceb 2004-04-24 devnull pt++;
230 8a3b2ceb 2004-04-24 devnull }
231 8a3b2ceb 2004-04-24 devnull }