GRASS GIS 8 Programmer's Manual 8.2.0(2022)-exported
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 */
35struct 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 */
78void 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 */
113static 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 */
168int 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 */
185int 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 */
202int 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 */
219int 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 */
232int gs_update_curmask(geosurf * surf)
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 */
363void 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}
struct BM * BM_create(int x, int y)
Create bitmap of dimension x/y and return structure token.
Definition: bitmap.c:60
int BM_set(struct BM *map, int x, int y, int val)
Sets bitmap value to 'val' at location 'x' 'y'.
Definition: bitmap.c:190
int BM_get(struct BM *map, int x, int y)
Gets 'val' from the bitmap.
Definition: bitmap.c:223
int BM_destroy(struct BM *map)
Destroy bitmap and free all associated memory.
Definition: bitmap.c:93
#define NULL
Definition: ccmath.h:32
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
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:933
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:969
void gs_set_maskmode(int invert)
Set geosurf mask mode.
Definition: gs.c:900
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:915
int gsbm_and_masks(struct BM *bmvar, struct BM *bmcon)
Mask bitmap (mask type ADD)
Definition: gs_bm.c:202
int gsbm_ornot_masks(struct BM *bmvar, struct BM *bmcon)
Mask bitmap (mask type ORNOT)
Definition: gs_bm.c:185
#define MASK_OR
mask types
Definition: gs_bm.c:96
#define MASK_AND
Definition: gs_bm.c:98
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
int gsbm_or_masks(struct BM *bmvar, struct BM *bmcon)
Mask bitmap (mask type OR)
Definition: gs_bm.c:168
#define MASK_ORNOT
Definition: gs_bm.c:97
#define MASK_XOR
Definition: gs_bm.c:99
int gs_update_curmask(geosurf *surf)
Update current maps.
Definition: gs_bm.c:232
int gsbm_xor_masks(struct BM *bmvar, struct BM *bmcon)
Mask bitmap (mask type XOR)
Definition: gs_bm.c:219
void print_bm(struct BM *bm)
Print bitmap to stderr.
Definition: gs_bm.c:363
void gsbm_zero_mask(struct BM *map)
Zero mask.
Definition: gs_bm.c:78
#define GET_MAPATT(buff, offset, att)
Definition: gsget.h:27