Loading...
Searching...
No Matches
gs_bm.c
Go to the documentation of this file.
/*!
\file lib/ogsf/gs_bm.c
\brief OGSF library - manipulating bitmaps (lower level functions)
GRASS OpenGL gsurf OGSF Library
(C) 1999-2008 by the GRASS Development Team
This program is free software under the
GNU General Public License (>=v2).
Read the file COPYING that comes with GRASS
for details.
\author Bill Brown USACERL, GMSL/University of Illinois (September 1993)
\author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
*/
#include <grass/gis.h>
#include <grass/glocale.h>
#include <grass/ogsf.h>
#include "gsget.h"
/*!
\brief Do combining of bitmaps, make bitmaps from other data w/maskval
\param frombuff data buffer
\param maskval mask type
\param rows number of rows
\param cols number of cols
\return pointer to BM struct
*/
struct BM *gsbm_make_mask(typbuff *frombuff, float maskval, int rows, int cols)
{
int i, j, ioff;
struct BM *bm;
float curval;
bm = BM_create(cols, rows);
if (frombuff) {
if (frombuff->bm) {
for (i = 0; i < rows; i++) {
ioff = i * cols;
for (j = 0; j < cols; j++) {
BM_set(bm, j, i, BM_get(frombuff->bm, j, i));
}
}
}
else {
for (i = 0; i < rows; i++) {
ioff = i * cols;
for (j = 0; j < cols; j++) {
if (GET_MAPATT(frombuff, (ioff + j), curval)) {
BM_set(bm, j, i, (curval == maskval));
}
else {
BM_set(bm, j, i, 0); /* doesn't mask nulls */
}
}
}
}
}
return (bm);
}
/*!
\brief Zero mask
\param map pointer to BM struct
*/
void gsbm_zero_mask(struct BM *map)
{
int numbytes;
unsigned char *buf;
numbytes = map->bytes * map->rows;
buf = map->data;
while (numbytes--) {
*buf++ = 0;
}
return;
}
/*!
\brief mask types
*/
#define MASK_OR 1
#define MASK_ORNOT 2
#define MASK_AND 3
#define MASK_XOR 4
/*!
\brief Mask bitmap
Must be same size, ORs bitmaps & stores in bmvar
\param bmvar bitmap (BM) to changed
\param bmcon bitmap (BM)
\param mask_type mask type (see mask types macros)
\return -1 on failure (bitmap mispatch)
\return 0 on success
*/
static int gsbm_masks(struct BM *bmvar, struct BM *bmcon, const int mask_type)
{
int i;
int varsize, consize, numbytes;
varsize = bmvar->rows * bmvar->cols;
consize = bmcon->rows * bmcon->cols;
numbytes = bmvar->bytes * bmvar->rows;
if (bmcon && bmvar) {
if (varsize != consize) {
G_warning(_("Bitmap mismatch"));
return (-1);
}
if (bmvar->sparse || bmcon->sparse)
return (-1);
switch (mask_type) {
case MASK_OR:
for (i = 0; i < numbytes; i++)
bmvar->data[i] |= bmcon->data[i];
break;
case MASK_ORNOT:
for (i = 0; i < numbytes; i++)
bmvar->data[i] |= ~bmcon->data[i];
break;
case MASK_AND:
for (i = 0; i < numbytes; i++)
bmvar->data[i] &= bmcon->data[i];
break;
case MASK_XOR:
for (i = 0; i < numbytes; i++)
bmvar->data[i] ^= bmcon->data[i];
break;
}
return (0);
}
return (-1);
}
/*!
\brief Mask bitmap (mask type OR)
Must be same size, ORs bitmaps & stores in bmvar
\param bmvar bitmap (BM) to changed
\param bmcon bitmap (BM)
\param mask_type mask type (see mask types macros)
\return -1 on failure (bitmap mispatch)
\return 0 on success
*/
int gsbm_or_masks(struct BM *bmvar, struct BM *bmcon)
{
return gsbm_masks(bmvar, bmcon, MASK_OR);
}
/*!
\brief Mask bitmap (mask type ORNOT)
Must be same size, ORNOTs bitmaps & stores in bmvar
\param bmvar bitmap (BM) to changed
\param bmcon bitmap (BM)
\return -1 on failure (bitmap mispatch)
\return 0 on success
*/
int gsbm_ornot_masks(struct BM *bmvar, struct BM *bmcon)
{
return gsbm_masks(bmvar, bmcon, MASK_ORNOT);
}
/*!
\brief Mask bitmap (mask type ADD)
Must be same size, ADDs bitmaps & stores in bmvar
\param bmvar bitmap (BM) to changed
\param bmcon bitmap (BM)
\return -1 on failure (bitmap mispatch)
\return 0 on success
*/
int gsbm_and_masks(struct BM *bmvar, struct BM *bmcon)
{
return gsbm_masks(bmvar, bmcon, MASK_AND);
}
/*!
\brief Mask bitmap (mask type XOR)
Must be same size, XORs bitmaps & stores in bmvar
\param bmvar bitmap (BM) to changed
\param bmcon bitmap (BM)
\return -1 on failure (bitmap mispatch)
\return 0 on success
*/
int gsbm_xor_masks(struct BM *bmvar, struct BM *bmcon)
{
return gsbm_masks(bmvar, bmcon, MASK_XOR);
}
/*!
\brief Update current maps
\param surf surface (geosurf)
\return 0
\return 1
*/
int gs_update_curmask(geosurf *surf)
{
struct BM *b_mask, *b_topo, *b_color;
typbuff *t_topo, *t_mask, *t_color;
int row, col, offset, destroy_ok = 1;
gsurf_att *coloratt;
G_debug(5, "gs_update_curmask(): id=%d", surf->gsurf_id);
if (surf->mask_needupdate) {
surf->mask_needupdate = 0;
surf->norm_needupdate = 1; /* edges will need to be recalculated */
t_topo = gs_get_att_typbuff(surf, ATT_TOPO, 0);
if (!t_topo) {
surf->mask_needupdate = 1;
return (0);
}
if (surf->nz_topo || surf->nz_color || gs_mask_defined(surf) ||
t_topo->nm) {
b_mask = b_topo = b_color = NULL;
if (!surf->curmask) {
surf->curmask = BM_create(surf->cols, surf->rows);
}
else {
gsbm_zero_mask(surf->curmask);
}
if (surf->nz_topo) {
/* no_zero elevation */
b_topo = gsbm_make_mask(t_topo, 0.0, surf->rows, surf->cols);
}
/* make_mask_from_color */
if (surf->nz_color && surf->att[ATT_COLOR].att_src == MAP_ATT) {
t_color = gs_get_att_typbuff(surf, ATT_COLOR, 0);
coloratt = &(surf->att[ATT_COLOR]);
b_color = BM_create(surf->cols, surf->rows);
for (row = 0; row < surf->rows; row++) {
for (col = 0; col < surf->cols; col++) {
offset = row * surf->cols + col;
BM_set(b_color, col, row,
(NULL_COLOR ==
gs_mapcolor(t_color, coloratt, offset)));
}
}
}
if (gs_mask_defined(surf)) {
t_mask = gs_get_att_typbuff(surf, ATT_MASK, 0);
if (t_mask->bm) {
b_mask = t_mask->bm;
destroy_ok = 0;
}
else {
b_mask = BM_create(surf->cols, surf->rows);
gs_set_maskmode((int)surf->att[ATT_MASK].constant);
for (row = 0; row < surf->rows; row++) {
for (col = 0; col < surf->cols; col++) {
offset = row * surf->cols + col;
BM_set(b_mask, col, row,
gs_masked(t_mask, col, row, offset));
}
}
}
}
if (b_topo) {
G_debug(5, "gs_update_curmask(): update topo mask");
gsbm_or_masks(surf->curmask, b_topo);
BM_destroy(b_topo);
}
if (b_color) {
G_debug(5, "gs_update_curmask(): update color mask");
gsbm_or_masks(surf->curmask, b_color);
BM_destroy(b_color);
}
if (t_topo->nm) {
G_debug(5, "gs_update_curmask(): update elev null mask");
gsbm_or_masks(surf->curmask, t_topo->nm);
}
if (b_mask) {
G_debug(5, "gs_update_curmask(): update mask mask");
if (t_mask->bm) {
if (surf->att[ATT_MASK].constant) {
/* invert */
gsbm_or_masks(surf->curmask, t_mask->bm);
}
else {
gsbm_ornot_masks(surf->curmask, t_mask->bm);
}
}
else {
gsbm_or_masks(surf->curmask, b_mask);
}
if (destroy_ok) {
BM_destroy(b_mask);
}
}
/* TODO: update surf->zminmasked */
return (1);
}
else if (surf->curmask) {
BM_destroy(surf->curmask);
surf->curmask = NULL;
surf->zminmasked = surf->zmin;
}
}
return (0);
}
/*!
\brief Print bitmap to stderr
\param bm bitmap (BM)
*/
void print_bm(struct BM *bm)
{
int i, j;
for (i = 0; i < bm->rows; i++) {
for (j = 0; j < bm->cols; j++) {
fprintf(stderr, "%d ", BM_get(bm, j, i));
}
fprintf(stderr, "\n");
}
return;
}
BM_create
struct BM * BM_create(int x, int y)
Create bitmap of dimension x/y and return structure token.
Definition bitmap.c:57
BM_set
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
BM_get
int BM_get(struct BM *map, int x, int y)
Gets 'val' from the bitmap.
Definition bitmap.c:213
BM_destroy
int BM_destroy(struct BM *map)
Destroy bitmap and free all associated memory.
Definition bitmap.c:88
NULL
#define NULL
Definition ccmath.h:32
G_debug
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition debug.c:66
G_warning
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition gis/error.c:203
gs_masked
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
gs_mapcolor
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
gs_set_maskmode
void gs_set_maskmode(int invert)
Set geosurf mask mode.
Definition gs.c:899
gs_get_att_typbuff
typbuff * gs_get_att_typbuff(geosurf *gs, int desc, int to_write)
Get attribute data buffer.
Definition gs.c:681
gs_mask_defined
int gs_mask_defined(geosurf *gs)
Check if mask is defined.
Definition gs.c:914
gsbm_and_masks
int gsbm_and_masks(struct BM *bmvar, struct BM *bmcon)
Mask bitmap (mask type ADD).
Definition gs_bm.c:199
gsbm_ornot_masks
int gsbm_ornot_masks(struct BM *bmvar, struct BM *bmcon)
Mask bitmap (mask type ORNOT).
Definition gs_bm.c:183
MASK_OR
#define MASK_OR
mask types
Definition gs_bm.c:95
MASK_AND
#define MASK_AND
Definition gs_bm.c:97
gsbm_make_mask
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
gsbm_or_masks
int gsbm_or_masks(struct BM *bmvar, struct BM *bmcon)
Mask bitmap (mask type OR).
Definition gs_bm.c:167
MASK_ORNOT
#define MASK_ORNOT
Definition gs_bm.c:96
MASK_XOR
#define MASK_XOR
Definition gs_bm.c:98
gs_update_curmask
int gs_update_curmask(geosurf *surf)
Update current maps.
Definition gs_bm.c:228
gsbm_xor_masks
int gsbm_xor_masks(struct BM *bmvar, struct BM *bmcon)
Mask bitmap (mask type XOR).
Definition gs_bm.c:215
print_bm
void print_bm(struct BM *bm)
Print bitmap to stderr.
Definition gs_bm.c:358
gsbm_zero_mask
void gsbm_zero_mask(struct BM *map)
Zero mask.
Definition gs_bm.c:77
gsget.h
GET_MAPATT
#define GET_MAPATT(buff, offset, att)
Definition gsget.h:29