hinv.c 4.7 KB

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