FFT.java 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. ** Copyright 2005 Huxtable.com. All rights reserved.
  3. */
  4. package com.cvte.blurfilter;
  5. public class FFT {
  6. // Weighting factors
  7. protected float[] w1;
  8. protected float[] w2;
  9. protected float[] w3;
  10. public FFT( int logN ) {
  11. // Prepare the weighting factors
  12. w1 = new float[logN];
  13. w2 = new float[logN];
  14. w3 = new float[logN];
  15. int N = 1;
  16. for ( int k = 0; k < logN; k++ ) {
  17. N <<= 1;
  18. double angle = -2.0 * Math.PI / N;
  19. w1[k] = (float)Math.sin(0.5 * angle);
  20. w2[k] = -2.0f * w1[k] * w1[k];
  21. w3[k] = (float)Math.sin(angle);
  22. }
  23. }
  24. private void scramble( int n, float[] real, float[] imag ) {
  25. int j = 0;
  26. for ( int i = 0; i < n; i++ ) {
  27. if ( i > j ) {
  28. float t;
  29. t = real[j];
  30. real[j] = real[i];
  31. real[i] = t;
  32. t = imag[j];
  33. imag[j] = imag[i];
  34. imag[i] = t;
  35. }
  36. int m = n >> 1;
  37. while (j >= m && m >= 2) {
  38. j -= m;
  39. m >>= 1;
  40. }
  41. j += m;
  42. }
  43. }
  44. private void butterflies( int n, int logN, int direction, float[] real, float[] imag ) {
  45. int N = 1;
  46. for ( int k = 0; k < logN; k++ ) {
  47. float w_re, w_im, wp_re, wp_im, temp_re, temp_im, wt;
  48. int half_N = N;
  49. N <<= 1;
  50. wt = direction * w1[k];
  51. wp_re = w2[k];
  52. wp_im = direction * w3[k];
  53. w_re = 1.0f;
  54. w_im = 0.0f;
  55. for ( int offset = 0; offset < half_N; offset++ ) {
  56. for( int i = offset; i < n; i += N ) {
  57. int j = i + half_N;
  58. float re = real[j];
  59. float im = imag[j];
  60. temp_re = (w_re * re) - (w_im * im);
  61. temp_im = (w_im * re) + (w_re * im);
  62. real[j] = real[i] - temp_re;
  63. real[i] += temp_re;
  64. imag[j] = imag[i] - temp_im;
  65. imag[i] += temp_im;
  66. }
  67. wt = w_re;
  68. w_re = wt * wp_re - w_im * wp_im + w_re;
  69. w_im = w_im * wp_re + wt * wp_im + w_im;
  70. }
  71. }
  72. if ( direction == -1 ) {
  73. float nr = 1.0f / n;
  74. for ( int i = 0; i < n; i++ ) {
  75. real[i] *= nr;
  76. imag[i] *= nr;
  77. }
  78. }
  79. }
  80. public void transform1D( float[] real, float[] imag, int logN, int n, boolean forward ) {
  81. scramble( n, real, imag );
  82. butterflies( n, logN, forward ? 1 : -1, real, imag );
  83. }
  84. public void transform2D( float[] real, float[] imag, int cols, int rows, boolean forward ) {
  85. int log2cols = log2(cols);
  86. int log2rows = log2(rows);
  87. int n = Math.max(rows, cols);
  88. float[] rtemp = new float[n];
  89. float[] itemp = new float[n];
  90. // FFT the rows
  91. for ( int y = 0; y < rows; y++ ) {
  92. int offset = y*cols;
  93. System.arraycopy( real, offset, rtemp, 0, cols );
  94. System.arraycopy( imag, offset, itemp, 0, cols );
  95. transform1D(rtemp, itemp, log2cols, cols, forward);
  96. System.arraycopy( rtemp, 0, real, offset, cols );
  97. System.arraycopy( itemp, 0, imag, offset, cols );
  98. }
  99. // FFT the columns
  100. for ( int x = 0; x < cols; x++ ) {
  101. int index = x;
  102. for ( int y = 0; y < rows; y++ ) {
  103. rtemp[y] = real[index];
  104. itemp[y] = imag[index];
  105. index += cols;
  106. }
  107. transform1D(rtemp, itemp, log2rows, rows, forward);
  108. index = x;
  109. for ( int y = 0; y < rows; y++ ) {
  110. real[index] = rtemp[y];
  111. imag[index] = itemp[y];
  112. index += cols;
  113. }
  114. }
  115. }
  116. private int log2( int n ) {
  117. int m = 1;
  118. int log2n = 0;
  119. while (m < n) {
  120. m *= 2;
  121. log2n++;
  122. }
  123. return m == n ? log2n : -1;
  124. }
  125. }