GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-112dd97adf
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 bmcom 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 bmcom 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 bmcom bitmap (BM)
179  \param mask_type mask type (see mask types macros)
180 
181  \return -1 on failure (bitmap mispatch)
182  \return 0 on success
183  */
184 int gsbm_ornot_masks(struct BM *bmvar, struct BM *bmcon)
185 {
186  return gsbm_masks(bmvar, bmcon, MASK_ORNOT);
187 }
188 
189 /*!
190  \brief Mask bitmap (mask type ADD)
191 
192  Must be same size, ADDs bitmaps & stores in bmvar
193 
194  \param bmvar bitmap (BM) to changed
195  \param bmcom bitmap (BM)
196  \param mask_type mask type (see mask types macros)
197 
198  \return -1 on failure (bitmap mispatch)
199  \return 0 on success
200  */
201 int gsbm_and_masks(struct BM *bmvar, struct BM *bmcon)
202 {
203  return gsbm_masks(bmvar, bmcon, MASK_AND);
204 }
205 
206 /*!
207  \brief Mask bitmap (mask type XOR)
208 
209  Must be same size, XORs bitmaps & stores in bmvar
210 
211  \param bmvar bitmap (BM) to changed
212  \param bmcom bitmap (BM)
213  \param mask_type mask type (see mask types macros)
214 
215  \return -1 on failure (bitmap mispatch)
216  \return 0 on success
217  */
218 int gsbm_xor_masks(struct BM *bmvar, struct BM *bmcon)
219 {
220  return gsbm_masks(bmvar, bmcon, MASK_XOR);
221 }
222 
223 /*!
224  \brief Update current maps
225 
226  \param surf surface (geosurf)
227 
228  \return 0
229  \return 1
230  */
232 {
233  struct BM *b_mask, *b_topo, *b_color;
234  typbuff *t_topo, *t_mask, *t_color;
235  int row, col, offset, destroy_ok = 1;
236  gsurf_att *coloratt;
237 
238  G_debug(5, "gs_update_curmask(): id=%d", surf->gsurf_id);
239 
240  if (surf->mask_needupdate) {
241  surf->mask_needupdate = 0;
242  surf->norm_needupdate = 1; /* edges will need to be recalculated */
243 
244  t_topo = gs_get_att_typbuff(surf, ATT_TOPO, 0);
245 
246  if (!t_topo) {
247  surf->mask_needupdate = 1;
248 
249  return (0);
250  }
251 
252  if (surf->nz_topo || surf->nz_color || gs_mask_defined(surf) ||
253  t_topo->nm) {
254  b_mask = b_topo = b_color = NULL;
255 
256  if (!surf->curmask) {
257  surf->curmask = BM_create(surf->cols, surf->rows);
258  }
259  else {
260  gsbm_zero_mask(surf->curmask);
261  }
262 
263  if (surf->nz_topo) {
264  /* no_zero elevation */
265  b_topo = gsbm_make_mask(t_topo, 0.0, surf->rows, surf->cols);
266  }
267 
268  /* make_mask_from_color */
269  if (surf->nz_color && surf->att[ATT_COLOR].att_src == MAP_ATT) {
270  t_color = gs_get_att_typbuff(surf, ATT_COLOR, 0);
271  coloratt = &(surf->att[ATT_COLOR]);
272  b_color = BM_create(surf->cols, surf->rows);
273 
274  for (row = 0; row < surf->rows; row++) {
275  for (col = 0; col < surf->cols; col++) {
276  offset = row * surf->cols + col;
277  BM_set(b_color, col, row,
278  (NULL_COLOR ==
279  gs_mapcolor(t_color, coloratt, offset)));
280  }
281  }
282  }
283 
284  if (gs_mask_defined(surf)) {
285  t_mask = gs_get_att_typbuff(surf, ATT_MASK, 0);
286 
287  if (t_mask->bm) {
288  b_mask = t_mask->bm;
289  destroy_ok = 0;
290  }
291  else {
292  b_mask = BM_create(surf->cols, surf->rows);
293  gs_set_maskmode((int)surf->att[ATT_MASK].constant);
294 
295  for (row = 0; row < surf->rows; row++) {
296  for (col = 0; col < surf->cols; col++) {
297  offset = row * surf->cols + col;
298  BM_set(b_mask, col, row,
299  gs_masked(t_mask, col, row, offset));
300  }
301  }
302  }
303  }
304 
305  if (b_topo) {
306  G_debug(5, "gs_update_curmask(): update topo mask");
307  gsbm_or_masks(surf->curmask, b_topo);
308  BM_destroy(b_topo);
309  }
310 
311  if (b_color) {
312  G_debug(5, "gs_update_curmask(): update color mask");
313  gsbm_or_masks(surf->curmask, b_color);
314  BM_destroy(b_color);
315  }
316 
317  if (t_topo->nm) {
318  G_debug(5, "gs_update_curmask(): update elev null mask");
319  gsbm_or_masks(surf->curmask, t_topo->nm);
320  }
321 
322  if (b_mask) {
323  G_debug(5, "gs_update_curmask(): update mask mask");
324 
325  if (t_mask->bm) {
326  if (surf->att[ATT_MASK].constant) {
327  /* invert */
328  gsbm_or_masks(surf->curmask, t_mask->bm);
329  }
330  else {
331  gsbm_ornot_masks(surf->curmask, t_mask->bm);
332  }
333  }
334  else {
335  gsbm_or_masks(surf->curmask, b_mask);
336  }
337 
338  if (destroy_ok) {
339  BM_destroy(b_mask);
340  }
341  }
342 
343  /* TODO: update surf->zminmasked */
344  return (1);
345  }
346  else if (surf->curmask) {
347  BM_destroy(surf->curmask);
348  surf->curmask = NULL;
349  surf->zminmasked = surf->zmin;
350  }
351  }
352 
353  return (0);
354 }
355 
356 /*!
357  \brief Print bitmap to stderr
358 
359  \param bm bitmap (BM)
360  */
361 void print_bm(struct BM *bm)
362 {
363  int i, j;
364 
365  for (i = 0; i < bm->rows; i++) {
366  for (j = 0; j < bm->cols; j++) {
367  fprintf(stderr, "%d ", BM_get(bm, j, i));
368  }
369 
370  fprintf(stderr, "\n");
371  }
372 
373  return;
374 }
#define NULL
Definition: ccmath.h:32
int BM_get(struct BM *, int, int)
Gets 'val' from the bitmap.
Definition: bitmap.c:217
int BM_destroy(struct BM *)
Destroy bitmap and free all associated memory.
Definition: bitmap.c:89
int BM_set(struct BM *, int, int, int)
Sets bitmap value to 'val' at location 'x' 'y'.
Definition: bitmap.c:185
struct BM * BM_create(int, int)
Create bitmap of dimension x/y and return structure token.
Definition: bitmap.c:58
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:201
int gsbm_ornot_masks(struct BM *bmvar, struct BM *bmcon)
Mask bitmap (mask type ORNOT)
Definition: gs_bm.c:184
#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:231
int gsbm_xor_masks(struct BM *bmvar, struct BM *bmcon)
Mask bitmap (mask type XOR)
Definition: gs_bm.c:218
void print_bm(struct BM *bm)
Print bitmap to stderr.
Definition: gs_bm.c:361
void gsbm_zero_mask(struct BM *map)
Zero mask.
Definition: gs_bm.c:77
#define GET_MAPATT(buff, offset, att)
Definition: gsget.h:29
#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:256
int nz_color
Definition: ogsf.h:271
int rows
Definition: ogsf.h:258
int cols
Definition: ogsf.h:258
gsurf_att att[MAX_ATTS]
Definition: ogsf.h:259
int gsurf_id
Definition: ogsf.h:257
struct BM * curmask
Definition: ogsf.h:274
int norm_needupdate
Definition: ogsf.h:272
int mask_needupdate
Definition: ogsf.h:272
int nz_topo
Definition: ogsf.h:271
float zmin
Definition: ogsf.h:267
float zminmasked
Definition: ogsf.h:267
float constant
Definition: ogsf.h:250
IFLAG att_src
Definition: ogsf.h:246
Definition: ogsf.h:208
struct BM * nm
Definition: ogsf.h:214
struct BM * bm
Definition: ogsf.h:213