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