main.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /****************************************************************************
  2. *
  3. * MODULE: i.ifft
  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 the real and imaginary Fourier
  10. * components in frequency space and constract raster map
  11. * COPYRIGHT: (C) 1999-2008 by the GRASS Development Team
  12. *
  13. * This program is free software under the GNU General Public
  14. * License (>=v2). Read the file COPYING that comes with GRASS
  15. * for details.
  16. *
  17. *****************************************************************************/
  18. /*
  19. Central Washington University GIS Laboratory
  20. Programmer: David B. Satnik
  21. and
  22. Programmer : Ali R. Vali
  23. Center for Space Research
  24. WRW 402
  25. University of Texas
  26. Austin, TX 78712-1085
  27. (512) 471-6824
  28. */
  29. #include <string.h>
  30. #include <stdlib.h>
  31. #include <math.h>
  32. #include <grass/gis.h>
  33. #include <grass/raster.h>
  34. #include <grass/glocale.h>
  35. #include <grass/gmath.h>
  36. static void fft_colors(const char *name)
  37. {
  38. struct Colors colors;
  39. struct FPRange range;
  40. DCELL min, max;
  41. /* make a real component color table */
  42. Rast_read_fp_range(name, G_mapset(), &range);
  43. Rast_get_fp_range_min_max(&range, &min, &max);
  44. Rast_make_grey_scale_fp_colors(&colors, min, max);
  45. Rast_write_colors(name, G_mapset(), &colors);
  46. }
  47. int main(int argc, char *argv[])
  48. {
  49. /* Global variable & function declarations */
  50. struct GModule *module;
  51. struct {
  52. struct Option *orig, *real, *imag;
  53. } opt;
  54. const char *Cellmap_real, *Cellmap_imag;
  55. const char *Cellmap_orig;
  56. int realfd, imagfd, outputfd, maskfd; /* the input and output file descriptors */
  57. struct Cell_head realhead, imaghead;
  58. DCELL *cell_real, *cell_imag;
  59. CELL *maskbuf;
  60. int i, j; /* Loop control variables */
  61. int rows, cols; /* number of rows & columns */
  62. long totsize; /* Total number of data points */
  63. double (*data)[2]; /* Data structure containing real & complex values of FFT */
  64. G_gisinit(argv[0]);
  65. /* Set description */
  66. module = G_define_module();
  67. G_add_keyword(_("imagery"));
  68. G_add_keyword(_("transformation"));
  69. G_add_keyword(_("Fast Fourier Transform"));
  70. module->description =
  71. _("Inverse Fast Fourier Transform (IFFT) for image processing.");
  72. /* define options */
  73. opt.real = G_define_standard_option(G_OPT_R_INPUT);
  74. opt.real->key = "real_image";
  75. opt.real->description = _("Name of input raster map (image fft, real part)");
  76. opt.imag = G_define_standard_option(G_OPT_R_INPUT);
  77. opt.imag->key = "imaginary_image";
  78. opt.imag->description = _("Name of input raster map (image fft, imaginary part");
  79. opt.orig = G_define_standard_option(G_OPT_R_OUTPUT);
  80. opt.orig->key = "output_image";
  81. opt.orig->description = _("Name for output raster map");
  82. /*call parser */
  83. if (G_parser(argc, argv))
  84. exit(EXIT_FAILURE);
  85. Cellmap_real = opt.real->answer;
  86. Cellmap_imag = opt.imag->answer;
  87. Cellmap_orig = opt.orig->answer;
  88. /* get and compare the original window data */
  89. Rast_get_cellhd(Cellmap_real, "", &realhead);
  90. Rast_get_cellhd(Cellmap_imag, "", &imaghead);
  91. if (realhead.proj != imaghead.proj ||
  92. realhead.zone != imaghead.zone ||
  93. realhead.north != imaghead.north ||
  94. realhead.south != imaghead.south ||
  95. realhead.east != imaghead.east ||
  96. realhead.west != imaghead.west ||
  97. realhead.ew_res != imaghead.ew_res ||
  98. realhead.ns_res != imaghead.ns_res)
  99. G_fatal_error(_("The real and imaginary original windows did not match"));
  100. Rast_set_window(&realhead); /* set the window to the whole cell map */
  101. /* open input raster map */
  102. realfd = Rast_open_old(Cellmap_real, "");
  103. imagfd = Rast_open_old(Cellmap_imag, "");
  104. /* get the rows and columns in the current window */
  105. rows = Rast_window_rows();
  106. cols = Rast_window_cols();
  107. totsize = rows * cols;
  108. /* Allocate appropriate memory for the structure containing
  109. the real and complex components of the FFT. DATA[0] will
  110. contain the real, and DATA[1] the complex component.
  111. */
  112. data = G_malloc(rows * cols * 2 * sizeof(double));
  113. /* allocate the space for one row of cell map data */
  114. cell_real = Rast_allocate_d_buf();
  115. cell_imag = Rast_allocate_d_buf();
  116. #define C(i, j) ((i) * cols + (j))
  117. /* Read in cell map values */
  118. G_message(_("Reading raster maps..."));
  119. for (i = 0; i < rows; i++) {
  120. Rast_get_d_row(realfd, cell_real, i);
  121. Rast_get_d_row(imagfd, cell_imag, i);
  122. for (j = 0; j < cols; j++) {
  123. data[C(i, j)][0] = cell_real[j];
  124. data[C(i, j)][1] = cell_imag[j];
  125. }
  126. G_percent(i+1, rows, 2);
  127. }
  128. /* close input cell maps */
  129. Rast_close(realfd);
  130. Rast_close(imagfd);
  131. /* Read in cell map values */
  132. G_message(_("Masking raster maps..."));
  133. maskfd = Rast_maskfd();
  134. if (maskfd >= 0) {
  135. maskbuf = Rast_allocate_c_buf();
  136. for (i = 0; i < rows; i++) {
  137. Rast_get_c_row(maskfd, maskbuf, i);
  138. for (j = 0; j < cols; j++) {
  139. if (maskbuf[j] == 0) {
  140. data[C(i, j)][0] = 0.0;
  141. data[C(i, j)][1] = 0.0;
  142. }
  143. }
  144. G_percent(i+1, rows, 2);
  145. }
  146. Rast_close(maskfd);
  147. G_free(maskbuf);
  148. }
  149. #define SWAP1(a, b) \
  150. do { \
  151. double temp = (a); \
  152. (a) = (b); \
  153. (b) = temp; \
  154. } while (0)
  155. #define SWAP2(a, b) \
  156. do { \
  157. SWAP1(data[(a)][0], data[(b)][0]); \
  158. SWAP1(data[(a)][1], data[(b)][1]); \
  159. } while (0)
  160. /* rotate the data array for standard display */
  161. G_message(_("Rotating data..."));
  162. for (i = 0; i < rows; i++)
  163. for (j = 0; j < cols / 2; j++)
  164. SWAP2(C(i, j), C(i, j + cols / 2));
  165. for (i = 0; i < rows / 2; i++)
  166. for (j = 0; j < cols; j++)
  167. SWAP2(C(i, j), C(i + rows / 2, j));
  168. /* perform inverse FFT */
  169. G_message(_("Starting Inverse FFT..."));
  170. fft2(1, data, totsize, cols, rows);
  171. /* open the output cell map */
  172. outputfd = Rast_open_fp_new(Cellmap_orig);
  173. /* Write out result to a new cell map */
  174. G_message(_("Writing raster map <%s>..."),
  175. Cellmap_orig);
  176. for (i = 0; i < rows; i++) {
  177. for (j = 0; j < cols; j++)
  178. cell_real[j] = data[C(i, j)][0];
  179. Rast_put_d_row(outputfd, cell_real);
  180. G_percent(i+1, rows, 2);
  181. }
  182. Rast_close(outputfd);
  183. G_free(cell_real);
  184. G_free(cell_imag);
  185. fft_colors(Cellmap_orig);
  186. /* Release memory resources */
  187. G_free(data);
  188. G_done_msg(" ");
  189. exit(EXIT_SUCCESS);
  190. }