hinv.c 4.3 KB

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