main.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /****************************************************************************
  2. *
  3. * MODULE: i.fft
  4. * AUTHOR(S): David B. Satnik and Ali R. Vali (original contributors),
  5. * Markus Neteler <neteler itc.it>
  6. * Bernhard Reiter <bernhard intevation.de>,
  7. * Brad Douglas <rez touchofmadness.com>,
  8. * Glynn Clements <glynn gclements.plus.com>
  9. * PURPOSE: processes a single input raster map layer
  10. * and constructs the real and imaginary Fourier
  11. * components in frequency space
  12. * COPYRIGHT: (C) 1999-2008 by the GRASS Development Team
  13. *
  14. * This program is free software under the GNU General Public
  15. * License (>=v2). Read the file COPYING that comes with GRASS
  16. * for details.
  17. *
  18. *****************************************************************************/
  19. /*
  20. FFT for GRASS by:
  21. Central Washington University GIS Laboratory
  22. Programmer: David B. Satnik
  23. Original FFT function provided by:
  24. Programmer : Ali R. Vali
  25. Center for Space Research
  26. WRW 402
  27. University of Texas
  28. Austin, TX 78712-1085
  29. (512) 471-6824
  30. */
  31. #include <string.h>
  32. #include <stdlib.h>
  33. #include <math.h>
  34. #include <grass/gis.h>
  35. #include <grass/raster.h>
  36. #include <grass/gmath.h>
  37. #include <grass/glocale.h>
  38. static void fft_colors(const char *name)
  39. {
  40. struct Colors wave, colors;
  41. struct FPRange range;
  42. DCELL min, max;
  43. Rast_read_fp_range(name, G_mapset(), &range);
  44. Rast_get_fp_range_min_max(&range, &min, &max);
  45. Rast_make_wave_colors(&wave, min, max);
  46. Rast_abs_log_colors(&colors, &wave, 100);
  47. Rast_write_colors(name, G_mapset(), &colors);
  48. Rast_free_colors(&colors);
  49. }
  50. int main(int argc, char *argv[])
  51. {
  52. /* Global variable & function declarations */
  53. struct GModule *module;
  54. struct {
  55. struct Option *orig, *real, *imag;
  56. } opt;
  57. const char *Cellmap_real, *Cellmap_imag;
  58. const char *Cellmap_orig;
  59. int inputfd, realfd, imagfd; /* the input and output file descriptors */
  60. struct Cell_head window;
  61. DCELL *cell_real, *cell_imag;
  62. int rows, cols; /* number of rows & columns */
  63. long totsize; /* Total number of data points */
  64. double (*data)[2]; /* Data structure containing real & complex values of FFT */
  65. int i, j; /* Loop control variables */
  66. G_gisinit(argv[0]);
  67. module = G_define_module();
  68. G_add_keyword(_("imagery"));
  69. G_add_keyword(_("transformation"));
  70. G_add_keyword(_("Fast Fourier Transform"));
  71. module->description =
  72. _("Fast Fourier Transform (FFT) for image processing.");
  73. /* define options */
  74. /* define options */
  75. opt.orig = G_define_standard_option(G_OPT_R_INPUT);
  76. opt.orig->key = "input_image";
  77. opt.real = G_define_standard_option(G_OPT_R_OUTPUT);
  78. opt.real->key = "real_image";
  79. opt.real->description = _("Name for output real part arrays stored as raster map");
  80. opt.imag = G_define_standard_option(G_OPT_R_OUTPUT);
  81. opt.imag->key = "imaginary_image";
  82. opt.imag->description = _("Name for output imaginary part arrays stored as raster map");
  83. if (G_parser(argc, argv))
  84. exit(EXIT_FAILURE);
  85. Cellmap_orig = opt.orig->answer;
  86. Cellmap_real = opt.real->answer;
  87. Cellmap_imag = opt.imag->answer;
  88. inputfd = Rast_open_old(Cellmap_orig, "");
  89. if (Rast_maskfd() >= 0)
  90. G_warning(_("Raster MASK found, consider to remove "
  91. "(see man-page). Will continue..."));
  92. G_get_set_window(&window); /* get the current window for later */
  93. /* get the rows and columns in the current window */
  94. rows = Rast_window_rows();
  95. cols = Rast_window_cols();
  96. totsize = rows * cols;
  97. /* Allocate appropriate memory for the structure containing
  98. the real and complex components of the FFT. data[...][0] will
  99. contain the real, and data[...][1] the complex component.
  100. */
  101. data = G_malloc(rows * cols * 2 * sizeof(double));
  102. /* allocate the space for one row of cell map data */
  103. cell_real = Rast_allocate_d_buf();
  104. cell_imag = Rast_allocate_d_buf();
  105. #define C(i, j) ((i) * cols + (j))
  106. /* Read in cell map values */
  107. G_message(_("Reading the raster map <%s>..."),
  108. Cellmap_orig);
  109. for (i = 0; i < rows; i++) {
  110. Rast_get_d_row(inputfd, cell_real, i);
  111. for (j = 0; j < cols; j++) {
  112. data[C(i, j)][0] = cell_real[j];
  113. data[C(i, j)][1] = 0.0;
  114. }
  115. G_percent(i+1, rows, 2);
  116. }
  117. /* close input cell map */
  118. Rast_close(inputfd);
  119. /* perform FFT */
  120. G_message(_("Starting FFT..."));
  121. fft2(-1, data, totsize, cols, rows);
  122. /* open the output cell maps */
  123. realfd = Rast_open_fp_new(Cellmap_real);
  124. imagfd = Rast_open_fp_new(Cellmap_imag);
  125. #define SWAP1(a, b) \
  126. do { \
  127. double temp = (a); \
  128. (a) = (b); \
  129. (b) = temp; \
  130. } while (0)
  131. #define SWAP2(a, b) \
  132. do { \
  133. SWAP1(data[(a)][0], data[(b)][0]); \
  134. SWAP1(data[(a)][1], data[(b)][1]); \
  135. } while (0)
  136. /* rotate the data array for standard display */
  137. G_message(_("Rotating data..."));
  138. for (i = 0; i < rows; i++)
  139. for (j = 0; j < cols / 2; j++)
  140. SWAP2(C(i, j), C(i, j + cols / 2));
  141. for (i = 0; i < rows / 2; i++)
  142. for (j = 0; j < cols; j++)
  143. SWAP2(C(i, j), C(i + rows / 2, j));
  144. G_message(_("Writing transformed data..."));
  145. for (i = 0; i < rows; i++) {
  146. for (j = 0; j < cols; j++) {
  147. cell_real[j] = data[C(i, j)][0];
  148. cell_imag[j] = data[C(i, j)][1];
  149. }
  150. Rast_put_d_row(realfd, cell_real);
  151. Rast_put_d_row(imagfd, cell_imag);
  152. G_percent(i+1, rows, 2);
  153. }
  154. Rast_close(realfd);
  155. Rast_close(imagfd);
  156. G_free(cell_real);
  157. G_free(cell_imag);
  158. /* set up the color tables */
  159. fft_colors(Cellmap_real);
  160. fft_colors(Cellmap_imag);
  161. /* Release memory resources */
  162. G_free(data);
  163. G_done_msg(_(" "));
  164. exit(EXIT_SUCCESS);
  165. }