GRASS Programmer's Manual
6.4.2(2012)
|
00001 00019 #include <grass/gis.h> 00020 #include <grass/glocale.h> 00021 #include <grass/gstypes.h> 00022 00023 #include "gsget.h" 00024 00035 struct BM *gsbm_make_mask(typbuff * frombuff, float maskval, int rows, 00036 int cols) 00037 { 00038 int i, j, ioff; 00039 struct BM *bm; 00040 float curval; 00041 00042 bm = BM_create(cols, rows); 00043 00044 if (frombuff) { 00045 if (frombuff->bm) { 00046 for (i = 0; i < rows; i++) { 00047 ioff = i * cols; 00048 00049 for (j = 0; j < cols; j++) { 00050 BM_set(bm, j, i, BM_get(frombuff->bm, j, i)); 00051 } 00052 } 00053 } 00054 else { 00055 for (i = 0; i < rows; i++) { 00056 ioff = i * cols; 00057 00058 for (j = 0; j < cols; j++) { 00059 if (GET_MAPATT(frombuff, (ioff + j), curval)) { 00060 BM_set(bm, j, i, (curval == maskval)); 00061 } 00062 else { 00063 BM_set(bm, j, i, 0); /* doesn't mask nulls */ 00064 } 00065 } 00066 } 00067 } 00068 } 00069 00070 return (bm); 00071 } 00072 00078 void gsbm_zero_mask(struct BM *map) 00079 { 00080 int numbytes; 00081 unsigned char *buf; 00082 00083 numbytes = map->bytes * map->rows; 00084 buf = map->data; 00085 00086 while (numbytes--) { 00087 *buf++ = 0; 00088 } 00089 00090 return; 00091 } 00092 00096 #define MASK_OR 1 00097 #define MASK_ORNOT 2 00098 #define MASK_AND 3 00099 #define MASK_XOR 4 00100 00113 static int gsbm_masks(struct BM *bmvar, struct BM *bmcon, const int mask_type) 00114 { 00115 int i; 00116 int varsize, consize, numbytes; 00117 00118 varsize = bmvar->rows * bmvar->cols; 00119 consize = bmcon->rows * bmcon->cols; 00120 numbytes = bmvar->bytes * bmvar->rows; 00121 00122 if (bmcon && bmvar) { 00123 if (varsize != consize) { 00124 G_warning(_("Bitmap mismatch")); 00125 return (-1); 00126 } 00127 00128 if (bmvar->sparse || bmcon->sparse) 00129 return (-1); 00130 00131 switch (mask_type) { 00132 case MASK_OR: 00133 for (i = 0; i < numbytes; i++) 00134 bmvar->data[i] |= bmcon->data[i]; 00135 break; 00136 case MASK_ORNOT: 00137 for (i = 0; i < numbytes; i++) 00138 bmvar->data[i] |= ~bmcon->data[i]; 00139 break; 00140 case MASK_AND: 00141 for (i = 0; i < numbytes; i++) 00142 bmvar->data[i] &= bmcon->data[i]; 00143 break; 00144 case MASK_XOR: 00145 for (i = 0; i < numbytes; i++) 00146 bmvar->data[i] ^= bmcon->data[i]; 00147 break; 00148 } 00149 00150 return (0); 00151 } 00152 00153 return (-1); 00154 } 00155 00168 int gsbm_or_masks(struct BM *bmvar, struct BM *bmcon) 00169 { 00170 return gsbm_masks(bmvar, bmcon, MASK_OR); 00171 } 00172 00185 int gsbm_ornot_masks(struct BM *bmvar, struct BM *bmcon) 00186 { 00187 return gsbm_masks(bmvar, bmcon, MASK_ORNOT); 00188 } 00189 00202 int gsbm_and_masks(struct BM *bmvar, struct BM *bmcon) 00203 { 00204 return gsbm_masks(bmvar, bmcon, MASK_AND); 00205 } 00206 00219 int gsbm_xor_masks(struct BM *bmvar, struct BM *bmcon) 00220 { 00221 return gsbm_masks(bmvar, bmcon, MASK_XOR); 00222 } 00223 00232 int gs_update_curmask(geosurf * surf) 00233 { 00234 struct BM *b_mask, *b_topo, *b_color; 00235 typbuff *t_topo, *t_mask, *t_color; 00236 int row, col, offset, destroy_ok = 1; 00237 gsurf_att *coloratt; 00238 00239 G_debug(5, "gs_update_curmask(): id=%d", surf->gsurf_id); 00240 00241 if (surf->mask_needupdate) { 00242 surf->mask_needupdate = 0; 00243 surf->norm_needupdate = 1; /* edges will need to be recalculated */ 00244 00245 t_topo = gs_get_att_typbuff(surf, ATT_TOPO, 0); 00246 00247 if (!t_topo) { 00248 surf->mask_needupdate = 1; 00249 00250 return (0); 00251 } 00252 00253 if (surf->nz_topo || surf->nz_color || 00254 gs_mask_defined(surf) || t_topo->nm) { 00255 b_mask = b_topo = b_color = NULL; 00256 00257 if (!surf->curmask) { 00258 surf->curmask = BM_create(surf->cols, surf->rows); 00259 } 00260 else { 00261 gsbm_zero_mask(surf->curmask); 00262 } 00263 00264 if (surf->nz_topo) { 00265 /* no_zero elevation */ 00266 b_topo = gsbm_make_mask(t_topo, 0.0, surf->rows, surf->cols); 00267 } 00268 00269 /* make_mask_from_color */ 00270 if (surf->nz_color && surf->att[ATT_COLOR].att_src == MAP_ATT) { 00271 t_color = gs_get_att_typbuff(surf, ATT_COLOR, 0); 00272 coloratt = &(surf->att[ATT_COLOR]); 00273 b_color = BM_create(surf->cols, surf->rows); 00274 00275 for (row = 0; row < surf->rows; row++) { 00276 for (col = 0; col < surf->cols; col++) { 00277 offset = row * surf->cols + col; 00278 BM_set(b_color, col, row, 00279 (NULL_COLOR == 00280 gs_mapcolor(t_color, coloratt, offset))); 00281 } 00282 } 00283 } 00284 00285 if (gs_mask_defined(surf)) { 00286 t_mask = gs_get_att_typbuff(surf, ATT_MASK, 0); 00287 00288 if (t_mask->bm) { 00289 b_mask = t_mask->bm; 00290 destroy_ok = 0; 00291 } 00292 else { 00293 b_mask = BM_create(surf->cols, surf->rows); 00294 gs_set_maskmode((int)surf->att[ATT_MASK].constant); 00295 00296 for (row = 0; row < surf->rows; row++) { 00297 for (col = 0; col < surf->cols; col++) { 00298 offset = row * surf->cols + col; 00299 BM_set(b_mask, col, row, 00300 gs_masked(t_mask, col, row, offset)); 00301 } 00302 } 00303 } 00304 } 00305 00306 if (b_topo) { 00307 G_debug(5, "gs_update_curmask(): update topo mask"); 00308 gsbm_or_masks(surf->curmask, b_topo); 00309 BM_destroy(b_topo); 00310 } 00311 00312 if (b_color) { 00313 G_debug(5, "gs_update_curmask(): update color mask"); 00314 gsbm_or_masks(surf->curmask, b_color); 00315 BM_destroy(b_color); 00316 } 00317 00318 if (t_topo->nm) { 00319 G_debug(5, "gs_update_curmask(): update elev null mask"); 00320 gsbm_or_masks(surf->curmask, t_topo->nm); 00321 } 00322 00323 if (b_mask) { 00324 G_debug(5, "gs_update_curmask(): update mask mask"); 00325 00326 if (t_mask->bm) { 00327 if (surf->att[ATT_MASK].constant) { 00328 /* invert */ 00329 gsbm_or_masks(surf->curmask, t_mask->bm); 00330 } 00331 else { 00332 gsbm_ornot_masks(surf->curmask, t_mask->bm); 00333 } 00334 } 00335 else { 00336 gsbm_or_masks(surf->curmask, b_mask); 00337 } 00338 00339 if (destroy_ok) { 00340 BM_destroy(b_mask); 00341 } 00342 } 00343 00344 /* TODO: update surf->zminmasked */ 00345 return (1); 00346 } 00347 else if (surf->curmask) { 00348 BM_destroy(surf->curmask); 00349 surf->curmask = NULL; 00350 surf->zminmasked = surf->zmin; 00351 } 00352 00353 } 00354 00355 return (0); 00356 } 00357 00363 void print_bm(struct BM *bm) 00364 { 00365 int i, j; 00366 00367 for (i = 0; i < bm->rows; i++) { 00368 for (j = 0; j < bm->cols; j++) { 00369 fprintf(stderr, "%d ", BM_get(bm, j, i)); 00370 } 00371 00372 fprintf(stderr, "\n"); 00373 } 00374 00375 return; 00376 }