main.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /****************************************************************************
  2. *
  3. * MODULE: r.out.ppm3
  4. * AUTHOR(S): Glynn Clements <glynn gclements.plus.com> (original contributor)
  5. * Jachym Cepicky <jachym les-ejk.cz>, Markus Neteler <neteler itc.it>
  6. * PURPOSE: Use to convert 3 grass raster layers (R,G,B) to PPM
  7. * uses currently selected region
  8. * COPYRIGHT: (C) 2001-2006 by the GRASS Development Team
  9. *
  10. * This program is free software under the GNU General Public
  11. * License (>=v2). Read the file COPYING that comes with GRASS
  12. * for details.
  13. *
  14. *****************************************************************************/
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include <grass/gis.h>
  18. #include <grass/raster.h>
  19. #include <grass/glocale.h>
  20. #define DEF_RED 255
  21. #define DEF_GRN 255
  22. #define DEF_BLU 255
  23. struct band
  24. {
  25. struct Option *opt;
  26. int file;
  27. int type;
  28. void *array;
  29. struct Colors colors;
  30. unsigned char *buf;
  31. unsigned char *mask;
  32. };
  33. static char *const color_names[3] = { "red", "green", "blue" };
  34. int main(int argc, char **argv)
  35. {
  36. struct band B[3];
  37. struct GModule *module;
  38. struct Option *ppm_file;
  39. struct Flag *comment;
  40. struct Cell_head w;
  41. FILE *fp;
  42. unsigned char *dummy;
  43. int row, col;
  44. int i;
  45. G_gisinit(argv[0]);
  46. module = G_define_module();
  47. G_add_keyword(_("raster"));
  48. G_add_keyword(_("export"));
  49. module->description = _("Converts 3 GRASS raster layers (R,G,B) to a PPM image file.");
  50. for (i = 0; i < 3; i++) {
  51. char buff[80];
  52. sprintf(buff, _("Name of raster map to be used for <%s>"),
  53. color_names[i]);
  54. B[i].opt = G_define_option();
  55. B[i].opt->key = G_store(color_names[i]);
  56. B[i].opt->type = TYPE_STRING;
  57. B[i].opt->answer = NULL;
  58. B[i].opt->required = YES;
  59. B[i].opt->multiple = NO;
  60. B[i].opt->gisprompt = "old,cell,raster";
  61. B[i].opt->description = G_store(buff);
  62. }
  63. ppm_file = G_define_option();
  64. ppm_file->key = "output";
  65. ppm_file->type = TYPE_STRING;
  66. ppm_file->required = YES;
  67. ppm_file->multiple = NO;
  68. ppm_file->answer = NULL;
  69. ppm_file->description =
  70. _("Name for new PPM file. (use out=- for stdout)");
  71. comment = G_define_flag();
  72. comment->key = 'c';
  73. comment->description = _("Add comments to describe the region");
  74. if (G_parser(argc, argv))
  75. exit(EXIT_FAILURE);
  76. G_get_window(&w);
  77. G_message(_("rows = %d, cols = %d"), w.rows, w.cols);
  78. /* open raster map for reading */
  79. for (i = 0; i < 3; i++) {
  80. /* Get name of layer */
  81. char *name = B[i].opt->answer;
  82. /* Open raster map */
  83. B[i].file = Rast_open_old(name, "");
  84. /* Get map type (CELL/FCELL/DCELL) */
  85. B[i].type = Rast_get_map_type(B[i].file);
  86. /* Get color table */
  87. if (Rast_read_colors(name, "", &B[i].colors) == -1)
  88. G_fatal_error(_("Color file for <%s> not available"), name);
  89. /* Allocate input buffer */
  90. B[i].array = Rast_allocate_buf(B[i].type);
  91. /* Allocate output buffers */
  92. B[i].buf = (unsigned char *)G_malloc(w.cols);
  93. B[i].mask = (unsigned char *)G_malloc(w.cols);
  94. }
  95. dummy = (unsigned char *)G_malloc(w.cols);
  96. /* open PPM file for writing */
  97. if (strcmp(ppm_file->answer, "-") == 0)
  98. fp = stdout;
  99. else {
  100. fp = fopen(ppm_file->answer, "w");
  101. if (!fp)
  102. G_fatal_error(_("Unable to open file <%s>"), ppm_file->answer);
  103. }
  104. /* write header info */
  105. /* Magic number meaning rawbits, 24bit color to PPM format */
  106. fprintf(fp, "P6\n");
  107. /* comments */
  108. if (comment->answer) {
  109. fprintf(fp, "# CREATOR: r.out.ppm3 (from GRASS)\n");
  110. fprintf(fp, "# Red: %s\n", B[0].opt->answer);
  111. fprintf(fp, "# Green: %s\n", B[1].opt->answer);
  112. fprintf(fp, "# Blue: %s\n", B[2].opt->answer);
  113. fprintf(fp, "# Projection: %s (Zone: %d)\n",
  114. G_database_projection_name(), G_zone());
  115. fprintf(fp, "# N=%f, S=%f, E=%f, W=%f\n",
  116. w.north, w.south, w.east, w.west);
  117. fprintf(fp, "# N/S Res: %f, E/W Res: %f\n", w.ns_res, w.ew_res);
  118. }
  119. /* width & height */
  120. fprintf(fp, "%d %d\n", w.cols, w.rows);
  121. /* max intensity val */
  122. fprintf(fp, "255\n");
  123. G_message(_("Converting ... "));
  124. for (row = 0; row < w.rows; row++) {
  125. G_percent(row, w.rows, 5);
  126. for (i = 0; i < 3; i++) {
  127. Rast_get_row(B[i].file, B[i].array, row, B[i].type);
  128. Rast_lookup_colors(B[i].array,
  129. (i == 0) ? B[i].buf : dummy,
  130. (i == 1) ? B[i].buf : dummy,
  131. (i == 2) ? B[i].buf : dummy,
  132. B[i].mask,
  133. w.cols, &B[i].colors, B[i].type);
  134. }
  135. for (col = 0; col < w.cols; col++) {
  136. if (B[0].mask && B[1].mask && B[2].mask) {
  137. putc(B[0].buf[col], fp);
  138. putc(B[1].buf[col], fp);
  139. putc(B[2].buf[col], fp);
  140. }
  141. else {
  142. putc(DEF_RED, fp);
  143. putc(DEF_GRN, fp);
  144. putc(DEF_BLU, fp);
  145. }
  146. }
  147. }
  148. fclose(fp);
  149. for (i = 0; i < 3; i++) {
  150. Rast_free_colors(&B[i].colors);
  151. G_free(B[i].array);
  152. G_free(B[i].buf);
  153. G_free(B[i].mask);
  154. Rast_close(B[i].file);
  155. }
  156. exit(EXIT_SUCCESS);
  157. }