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