raster.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #include <grass/gis.h>
  2. #include <grass/raster.h>
  3. #include "format.h"
  4. #include "local_proto.h"
  5. struct Cell_head region, page;
  6. static union
  7. {
  8. char **c;
  9. unsigned char **u;
  10. short **s;
  11. CELL **cell;
  12. } raster;
  13. static int max_rows;
  14. static int at_row;
  15. static long cat;
  16. static int cur_x, cur_y;
  17. static int format;
  18. static CELL *cell;
  19. static int (*dot) ();
  20. static int cell_dot(int, int);
  21. static int uchar_dot(int, int);
  22. static int char_dot(int, int);
  23. static int short_dot(int, int);
  24. static int move(int, int);
  25. static int cont(int, int);
  26. int begin_rasterization(int nrows, int f)
  27. {
  28. int i, size;
  29. int pages;
  30. format = f;
  31. max_rows = nrows;
  32. if (max_rows <= 0)
  33. max_rows = 512;
  34. Rast_get_window(&region);
  35. Rast_get_window(&page);
  36. pages = (region.rows + max_rows - 1) / max_rows;
  37. if (max_rows > region.rows)
  38. max_rows = region.rows;
  39. size = max_rows * region.cols;
  40. switch (format) {
  41. case USE_CHAR:
  42. raster.c = (char **)G_calloc(max_rows, sizeof(char *));
  43. raster.c[0] = (char *)G_calloc(size, sizeof(char));
  44. for (i = 1; i < max_rows; i++)
  45. raster.c[i] = raster.c[i - 1] + region.cols;
  46. dot = char_dot;
  47. break;
  48. case USE_UCHAR:
  49. raster.u =
  50. (unsigned char **)G_calloc(max_rows, sizeof(unsigned char *));
  51. raster.u[0] = (unsigned char *)G_calloc(size, sizeof(unsigned char));
  52. for (i = 1; i < max_rows; i++)
  53. raster.u[i] = raster.u[i - 1] + region.cols;
  54. dot = uchar_dot;
  55. break;
  56. case USE_SHORT:
  57. raster.s = (short **)G_calloc(max_rows, sizeof(short *));
  58. raster.s[0] = (short *)G_calloc(size, sizeof(short));
  59. for (i = 1; i < max_rows; i++)
  60. raster.s[i] = raster.s[i - 1] + region.cols;
  61. dot = short_dot;
  62. break;
  63. case USE_CELL:
  64. raster.cell = (CELL **) G_calloc(max_rows, sizeof(CELL *));
  65. raster.cell[0] = (CELL *) G_calloc(size, sizeof(CELL));
  66. for (i = 1; i < max_rows; i++)
  67. raster.cell[i] = raster.cell[i - 1] + region.cols;
  68. dot = cell_dot;
  69. break;
  70. }
  71. if (format != USE_CELL)
  72. cell = Rast_allocate_c_buf();
  73. at_row = 0;
  74. configure_plot();
  75. return pages;
  76. }
  77. #define DONE 1
  78. #define ERROR -1
  79. #define AGAIN 0
  80. int configure_plot(void)
  81. {
  82. int i, j;
  83. int nrows;
  84. int ncols;
  85. nrows = region.rows - at_row;
  86. if (nrows <= 0)
  87. return DONE;
  88. if (nrows > max_rows)
  89. nrows = max_rows;
  90. ncols = region.cols;
  91. /* zero the raster */
  92. switch (format) {
  93. case USE_CHAR:
  94. for (i = 0; i < nrows; i++)
  95. for (j = 0; j < ncols; j++)
  96. raster.c[i][j] = 0;
  97. break;
  98. case USE_UCHAR:
  99. for (i = 0; i < nrows; i++)
  100. for (j = 0; j < ncols; j++)
  101. raster.u[i][j] = 0;
  102. break;
  103. case USE_SHORT:
  104. for (i = 0; i < nrows; i++)
  105. for (j = 0; j < ncols; j++)
  106. raster.s[i][j] = 0;
  107. break;
  108. case USE_CELL:
  109. for (i = 0; i < nrows; i++)
  110. for (j = 0; j < ncols; j++)
  111. raster.cell[i][j] = 0;
  112. break;
  113. }
  114. /* change the region */
  115. page.north = region.north - at_row * region.ns_res;
  116. page.south = page.north - nrows * region.ns_res;
  117. /* Rast_set_[inpu|output]_window not working but G_set_window ??? */
  118. G_set_window(&page);
  119. /* configure the plot routines */
  120. G_setup_plot(-0.5, page.rows - 0.5, -0.5, page.cols - 0.5, move, cont);
  121. return AGAIN;
  122. }
  123. int output_raster(int fd)
  124. {
  125. int i, j;
  126. for (i = 0; i < page.rows; i++, at_row++) {
  127. switch (format) {
  128. case USE_CHAR:
  129. for (j = 0; j < page.cols; j++) {
  130. cell[j] = (CELL) raster.c[i][j];
  131. if (cell[j] == 0)
  132. Rast_set_null_value(&cell[j], 1, CELL_TYPE);
  133. }
  134. break;
  135. case USE_UCHAR:
  136. for (j = 0; j < page.cols; j++) {
  137. cell[j] = (CELL) raster.u[i][j];
  138. if (cell[j] == 0)
  139. Rast_set_null_value(&cell[j], 1, CELL_TYPE);
  140. }
  141. break;
  142. case USE_SHORT:
  143. for (j = 0; j < page.cols; j++) {
  144. cell[j] = (CELL) raster.s[i][j];
  145. if (cell[j] == 0)
  146. Rast_set_null_value(&cell[j], 1, CELL_TYPE);
  147. }
  148. break;
  149. case USE_CELL:
  150. cell = raster.cell[i];
  151. if (cell == 0)
  152. Rast_set_null_value(&cell, 1, CELL_TYPE);
  153. break;
  154. }
  155. G_percent(i, page.rows, 2);
  156. Rast_put_row(fd, cell, CELL_TYPE);
  157. }
  158. G_percent(i, page.rows, 2);
  159. return configure_plot();
  160. }
  161. int set_cat(long x)
  162. {
  163. cat = x;
  164. return 0;
  165. }
  166. int raster_dot(int x, int y)
  167. {
  168. dot(x, y);
  169. return 0;
  170. }
  171. static int move(int x, int y)
  172. {
  173. cur_x = x;
  174. cur_y = y;
  175. return 0;
  176. }
  177. static int cont(int x, int y)
  178. {
  179. if (cur_x < 0 && x < 0)
  180. goto set;
  181. if (cur_y < 0 && y < 0)
  182. goto set;
  183. if (cur_x >= page.cols && x >= page.cols)
  184. goto set;
  185. if (cur_y >= page.rows && y >= page.rows)
  186. goto set;
  187. G_bresenham_line(cur_x, cur_y, x, y, dot);
  188. set:
  189. move(x, y);
  190. return 0;
  191. }
  192. static int cell_dot(int x, int y)
  193. {
  194. if (x >= 0 && x < page.cols && y >= 0 && y < page.rows)
  195. raster.cell[y][x] = cat;
  196. return 0;
  197. }
  198. static int uchar_dot(int x, int y)
  199. {
  200. if (x >= 0 && x < page.cols && y >= 0 && y < page.rows)
  201. raster.u[y][x] = cat;
  202. return 0;
  203. }
  204. static int char_dot(int x, int y)
  205. {
  206. if (x >= 0 && x < page.cols && y >= 0 && y < page.rows)
  207. raster.c[y][x] = cat;
  208. return 0;
  209. }
  210. static int short_dot(int x, int y)
  211. {
  212. if (x >= 0 && x < page.cols && y >= 0 && y < page.rows)
  213. raster.s[y][x] = cat;
  214. return 0;
  215. }