GRASS 8 Programmer's Manual  8.5.0dev(2025)-c070206eb1
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  */
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 }
#define NULL
Definition: ccmath.h:32
int BM_get(struct BM *, int, int)
Gets 'val' from the bitmap.
Definition: bitmap.c:213
int BM_destroy(struct BM *)
Destroy bitmap and free all associated memory.
Definition: bitmap.c:88
int BM_set(struct BM *, int, int, int)
Sets bitmap value to 'val' at location 'x' 'y'.
Definition: bitmap.c:182
struct BM * BM_create(int, int)
Create bitmap of dimension x/y and return structure token.
Definition: bitmap.c:57
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
int gs_masked(typbuff *, int, int, int)
Should only be called when setting up the current mask (gs_bm.c)
Definition: gs.c:932
int gs_mapcolor(typbuff *, gsurf_att *, int)
Call this one when you already know att_src is MAP_ATT.
Definition: gs.c:968
typbuff * gs_get_att_typbuff(geosurf *, int, int)
Get attribute data buffer.
Definition: gs.c:681
void gs_set_maskmode(int)
Set geosurf mask mode.
Definition: gs.c:899
int gs_mask_defined(geosurf *)
Check if mask is defined.
Definition: gs.c:914
#define _(str)
Definition: glocale.h:10
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
OGSF header file (structures)
#define ATT_MASK
Definition: ogsf.h:77
#define ATT_TOPO
Definition: ogsf.h:75
#define NULL_COLOR
Definition: ogsf.h:158
#define ATT_COLOR
Definition: ogsf.h:76
#define MAP_ATT
Definition: ogsf.h:85
Definition: bitmap.h:17
int rows
Definition: bitmap.h:18
int cols
Definition: bitmap.h:19
unsigned char * data
Definition: bitmap.h:21
size_t bytes
Definition: bitmap.h:20
int sparse
Definition: bitmap.h:22
Definition: ogsf.h:266
int nz_color
Definition: ogsf.h:291
int rows
Definition: ogsf.h:268
int cols
Definition: ogsf.h:268
gsurf_att att[7]
mask, topo, color, etc.
Definition: ogsf.h:271
int gsurf_id
Definition: ogsf.h:267
struct BM * curmask
Definition: ogsf.h:294
int norm_needupdate
Definition: ogsf.h:292
int mask_needupdate
Definition: ogsf.h:292
int nz_topo
no zero flags
Definition: ogsf.h:291
float zmin
Definition: ogsf.h:284
float zminmasked
Definition: ogsf.h:284
float constant
Definition: ogsf.h:258
unsigned int att_src
NOTSET_ATT, MAP_ATT, CONST_ATT, FUNC_ATT.
Definition: ogsf.h:248
Definition: ogsf.h:208
struct BM * nm
Definition: ogsf.h:214
struct BM * bm
Definition: ogsf.h:213