gs_bm.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /*!
  2. \file lib/ogsf/gs_bm.c
  3. \brief OGSF library - manipulating bitmaps (lower level functions)
  4. GRASS OpenGL gsurf OGSF Library
  5. (C) 1999-2008 by the GRASS Development Team
  6. This program is free software under the
  7. GNU General Public License (>=v2).
  8. Read the file COPYING that comes with GRASS
  9. for details.
  10. \author Bill Brown USACERL, GMSL/University of Illinois (September 1993)
  11. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  12. */
  13. #include <grass/gis.h>
  14. #include <grass/glocale.h>
  15. #include <grass/ogsf.h>
  16. #include "gsget.h"
  17. /*!
  18. \brief Do combining of bitmaps, make bitmaps from other data w/maskval
  19. \param frombuff data buffer
  20. \param maskval mask type
  21. \param rows number of rows
  22. \param cols number of cols
  23. \return pointer to BM struct
  24. */
  25. struct BM *gsbm_make_mask(typbuff * frombuff, float maskval, int rows,
  26. int cols)
  27. {
  28. int i, j, ioff;
  29. struct BM *bm;
  30. float curval;
  31. bm = BM_create(cols, rows);
  32. if (frombuff) {
  33. if (frombuff->bm) {
  34. for (i = 0; i < rows; i++) {
  35. ioff = i * cols;
  36. for (j = 0; j < cols; j++) {
  37. BM_set(bm, j, i, BM_get(frombuff->bm, j, i));
  38. }
  39. }
  40. }
  41. else {
  42. for (i = 0; i < rows; i++) {
  43. ioff = i * cols;
  44. for (j = 0; j < cols; j++) {
  45. if (GET_MAPATT(frombuff, (ioff + j), curval)) {
  46. BM_set(bm, j, i, (curval == maskval));
  47. }
  48. else {
  49. BM_set(bm, j, i, 0); /* doesn't mask nulls */
  50. }
  51. }
  52. }
  53. }
  54. }
  55. return (bm);
  56. }
  57. /*!
  58. \brief Zero mask
  59. \param map pointer to BM struct
  60. */
  61. void gsbm_zero_mask(struct BM *map)
  62. {
  63. int numbytes;
  64. unsigned char *buf;
  65. numbytes = map->bytes * map->rows;
  66. buf = map->data;
  67. while (numbytes--) {
  68. *buf++ = 0;
  69. }
  70. return;
  71. }
  72. /*!
  73. \brief mask types
  74. */
  75. #define MASK_OR 1
  76. #define MASK_ORNOT 2
  77. #define MASK_AND 3
  78. #define MASK_XOR 4
  79. /*!
  80. \brief Mask bitmap
  81. Must be same size, ORs bitmaps & stores in bmvar
  82. \param bmvar bitmap (BM) to changed
  83. \param bmcom bitmap (BM)
  84. \param mask_type mask type (see mask types macros)
  85. \return -1 on failure (bitmap mispatch)
  86. \return 0 on success
  87. */
  88. static int gsbm_masks(struct BM *bmvar, struct BM *bmcon, const int mask_type)
  89. {
  90. int i;
  91. int varsize, consize, numbytes;
  92. varsize = bmvar->rows * bmvar->cols;
  93. consize = bmcon->rows * bmcon->cols;
  94. numbytes = bmvar->bytes * bmvar->rows;
  95. if (bmcon && bmvar) {
  96. if (varsize != consize) {
  97. G_warning(_("Bitmap mismatch"));
  98. return (-1);
  99. }
  100. if (bmvar->sparse || bmcon->sparse)
  101. return (-1);
  102. switch (mask_type) {
  103. case MASK_OR:
  104. for (i = 0; i < numbytes; i++)
  105. bmvar->data[i] |= bmcon->data[i];
  106. break;
  107. case MASK_ORNOT:
  108. for (i = 0; i < numbytes; i++)
  109. bmvar->data[i] |= ~bmcon->data[i];
  110. break;
  111. case MASK_AND:
  112. for (i = 0; i < numbytes; i++)
  113. bmvar->data[i] &= bmcon->data[i];
  114. break;
  115. case MASK_XOR:
  116. for (i = 0; i < numbytes; i++)
  117. bmvar->data[i] ^= bmcon->data[i];
  118. break;
  119. }
  120. return (0);
  121. }
  122. return (-1);
  123. }
  124. /*!
  125. \brief Mask bitmap (mask type OR)
  126. Must be same size, ORs bitmaps & stores in bmvar
  127. \param bmvar bitmap (BM) to changed
  128. \param bmcom bitmap (BM)
  129. \param mask_type mask type (see mask types macros)
  130. \return -1 on failure (bitmap mispatch)
  131. \return 0 on success
  132. */
  133. int gsbm_or_masks(struct BM *bmvar, struct BM *bmcon)
  134. {
  135. return gsbm_masks(bmvar, bmcon, MASK_OR);
  136. }
  137. /*!
  138. \brief Mask bitmap (mask type ORNOT)
  139. Must be same size, ORNOTs bitmaps & stores in bmvar
  140. \param bmvar bitmap (BM) to changed
  141. \param bmcom bitmap (BM)
  142. \param mask_type mask type (see mask types macros)
  143. \return -1 on failure (bitmap mispatch)
  144. \return 0 on success
  145. */
  146. int gsbm_ornot_masks(struct BM *bmvar, struct BM *bmcon)
  147. {
  148. return gsbm_masks(bmvar, bmcon, MASK_ORNOT);
  149. }
  150. /*!
  151. \brief Mask bitmap (mask type ADD)
  152. Must be same size, ADDs bitmaps & stores in bmvar
  153. \param bmvar bitmap (BM) to changed
  154. \param bmcom bitmap (BM)
  155. \param mask_type mask type (see mask types macros)
  156. \return -1 on failure (bitmap mispatch)
  157. \return 0 on success
  158. */
  159. int gsbm_and_masks(struct BM *bmvar, struct BM *bmcon)
  160. {
  161. return gsbm_masks(bmvar, bmcon, MASK_AND);
  162. }
  163. /*!
  164. \brief Mask bitmap (mask type XOR)
  165. Must be same size, XORs bitmaps & stores in bmvar
  166. \param bmvar bitmap (BM) to changed
  167. \param bmcom bitmap (BM)
  168. \param mask_type mask type (see mask types macros)
  169. \return -1 on failure (bitmap mispatch)
  170. \return 0 on success
  171. */
  172. int gsbm_xor_masks(struct BM *bmvar, struct BM *bmcon)
  173. {
  174. return gsbm_masks(bmvar, bmcon, MASK_XOR);
  175. }
  176. /*!
  177. \brief Update current maps
  178. \param surf surface (geosurf)
  179. \return 0
  180. \return 1
  181. */
  182. int gs_update_curmask(geosurf * surf)
  183. {
  184. struct BM *b_mask, *b_topo, *b_color;
  185. typbuff *t_topo, *t_mask, *t_color;
  186. int row, col, offset, destroy_ok = 1;
  187. gsurf_att *coloratt;
  188. G_debug(5, "gs_update_curmask(): id=%d", surf->gsurf_id);
  189. if (surf->mask_needupdate) {
  190. surf->mask_needupdate = 0;
  191. surf->norm_needupdate = 1; /* edges will need to be recalculated */
  192. t_topo = gs_get_att_typbuff(surf, ATT_TOPO, 0);
  193. if (!t_topo) {
  194. surf->mask_needupdate = 1;
  195. return (0);
  196. }
  197. if (surf->nz_topo || surf->nz_color ||
  198. gs_mask_defined(surf) || t_topo->nm) {
  199. b_mask = b_topo = b_color = NULL;
  200. if (!surf->curmask) {
  201. surf->curmask = BM_create(surf->cols, surf->rows);
  202. }
  203. else {
  204. gsbm_zero_mask(surf->curmask);
  205. }
  206. if (surf->nz_topo) {
  207. /* no_zero elevation */
  208. b_topo = gsbm_make_mask(t_topo, 0.0, surf->rows, surf->cols);
  209. }
  210. /* make_mask_from_color */
  211. if (surf->nz_color && surf->att[ATT_COLOR].att_src == MAP_ATT) {
  212. t_color = gs_get_att_typbuff(surf, ATT_COLOR, 0);
  213. coloratt = &(surf->att[ATT_COLOR]);
  214. b_color = BM_create(surf->cols, surf->rows);
  215. for (row = 0; row < surf->rows; row++) {
  216. for (col = 0; col < surf->cols; col++) {
  217. offset = row * surf->cols + col;
  218. BM_set(b_color, col, row,
  219. (NULL_COLOR ==
  220. gs_mapcolor(t_color, coloratt, offset)));
  221. }
  222. }
  223. }
  224. if (gs_mask_defined(surf)) {
  225. t_mask = gs_get_att_typbuff(surf, ATT_MASK, 0);
  226. if (t_mask->bm) {
  227. b_mask = t_mask->bm;
  228. destroy_ok = 0;
  229. }
  230. else {
  231. b_mask = BM_create(surf->cols, surf->rows);
  232. gs_set_maskmode((int)surf->att[ATT_MASK].constant);
  233. for (row = 0; row < surf->rows; row++) {
  234. for (col = 0; col < surf->cols; col++) {
  235. offset = row * surf->cols + col;
  236. BM_set(b_mask, col, row,
  237. gs_masked(t_mask, col, row, offset));
  238. }
  239. }
  240. }
  241. }
  242. if (b_topo) {
  243. G_debug(5, "gs_update_curmask(): update topo mask");
  244. gsbm_or_masks(surf->curmask, b_topo);
  245. BM_destroy(b_topo);
  246. }
  247. if (b_color) {
  248. G_debug(5, "gs_update_curmask(): update color mask");
  249. gsbm_or_masks(surf->curmask, b_color);
  250. BM_destroy(b_color);
  251. }
  252. if (t_topo->nm) {
  253. G_debug(5, "gs_update_curmask(): update elev null mask");
  254. gsbm_or_masks(surf->curmask, t_topo->nm);
  255. }
  256. if (b_mask) {
  257. G_debug(5, "gs_update_curmask(): update mask mask");
  258. if (t_mask->bm) {
  259. if (surf->att[ATT_MASK].constant) {
  260. /* invert */
  261. gsbm_or_masks(surf->curmask, t_mask->bm);
  262. }
  263. else {
  264. gsbm_ornot_masks(surf->curmask, t_mask->bm);
  265. }
  266. }
  267. else {
  268. gsbm_or_masks(surf->curmask, b_mask);
  269. }
  270. if (destroy_ok) {
  271. BM_destroy(b_mask);
  272. }
  273. }
  274. /* TODO: update surf->zminmasked */
  275. return (1);
  276. }
  277. else if (surf->curmask) {
  278. BM_destroy(surf->curmask);
  279. surf->curmask = NULL;
  280. surf->zminmasked = surf->zmin;
  281. }
  282. }
  283. return (0);
  284. }
  285. /*!
  286. \brief Print bitmap to stderr
  287. \param bm bitmap (BM)
  288. */
  289. void print_bm(struct BM *bm)
  290. {
  291. int i, j;
  292. for (i = 0; i < bm->rows; i++) {
  293. for (j = 0; j < bm->cols; j++) {
  294. fprintf(stderr, "%d ", BM_get(bm, j, i));
  295. }
  296. fprintf(stderr, "\n");
  297. }
  298. return;
  299. }