GRASS Programmer's Manual
6.4.2(2012)
|
00001 00056 #include <stdlib.h> 00057 #include <string.h> 00058 00059 #include <grass/gis.h> 00060 #include <grass/glocale.h> 00061 #include <grass/gstypes.h> 00062 00063 #define LUCKY 33 00064 #define BLOC 20 00065 #define MAX_DS 100 00066 00067 static int init_gsds(void); 00068 static int check_numsets(void); 00069 static dataset *get_dataset(int); 00070 static int get_type(dataset *); 00071 00072 static dataset *Data[MAX_DS]; 00073 static dataset Ds[MAX_DS]; /* trying to avoid allocation */ 00074 00075 static int Numsets = 0; 00076 00077 static int Cur_id = LUCKY; 00078 static int Cur_max; 00079 static int Tot_mem = 0; 00080 00084 static int init_gsds(void) 00085 { 00086 int i; 00087 00088 for (i = 0; i < MAX_DS; i++) { 00089 /* avoiding dynamic allocation */ 00090 Data[i] = &(Ds[i]); 00091 } 00092 00093 Cur_max = MAX_DS; 00094 00095 return (1); 00096 } 00097 00103 static int check_numsets(void) 00104 { 00105 if (Numsets < Cur_max) { 00106 return (0); 00107 } 00108 00109 G_fatal_error(_("Maximum number of datasets exceeded")); 00110 00111 /* This return statement keeps compilers happy, it is never executed */ 00112 return (0); 00113 } 00114 00123 static dataset *get_dataset(int id) 00124 { 00125 int i; 00126 00127 for (i = 0; i < Numsets; i++) { 00128 if (Data[i]->data_id == id) { 00129 return (Data[i]); 00130 } 00131 } 00132 00133 return (NULL); 00134 } 00135 00144 static int get_type(dataset * ds) 00145 { 00146 if (ds) { 00147 if (ds->databuff.bm) { 00148 return (ATTY_MASK); 00149 } 00150 00151 if (ds->databuff.cb) { 00152 return (ATTY_CHAR); 00153 } 00154 00155 if (ds->databuff.sb) { 00156 return (ATTY_SHORT); 00157 } 00158 00159 if (ds->databuff.ib) { 00160 return (ATTY_INT); 00161 } 00162 00163 if (ds->databuff.fb) { 00164 return (ATTY_FLOAT); 00165 } 00166 } 00167 00168 return (-1); 00169 } 00170 00188 int gsds_findh(const char *name, IFLAG * changes, IFLAG * types, int begin) 00189 { 00190 static int i; 00191 int start; 00192 00193 start = begin ? 0 : i + 1; 00194 00195 for (i = start; i < Numsets; i++) { 00196 if (!strcmp(Data[i]->unique_name, name)) { 00197 if ((Data[i]->changed & *changes) || !(Data[i]->changed)) { 00198 if (get_type(Data[i]) & *types) { 00199 *changes = Data[i]->changed; 00200 *types = get_type(Data[i]); 00201 00202 return (Data[i]->data_id); 00203 } 00204 } 00205 } 00206 } 00207 00208 return (-1); 00209 } 00210 00219 int gsds_newh(const char *name) 00220 { 00221 dataset *new; 00222 static int first = 1; 00223 int i; 00224 00225 if (first) { 00226 if (0 > init_gsds()) { 00227 return (-1); 00228 } 00229 00230 first = 0; 00231 } 00232 else if (0 > check_numsets()) { 00233 return (-1); 00234 } 00235 00236 if (!name) { 00237 return (-1); 00238 } 00239 00240 new = Data[Numsets]; 00241 00242 if (new) { 00243 Numsets++; 00244 new->data_id = Cur_id++; 00245 00246 for (i = 0; i < MAXDIMS; i++) { 00247 new->dims[i] = 0; 00248 } 00249 00250 new->unique_name = G_store(name); 00251 new->databuff.fb = NULL; 00252 new->databuff.ib = NULL; 00253 new->databuff.sb = NULL; 00254 new->databuff.cb = NULL; 00255 new->databuff.bm = NULL; 00256 new->databuff.nm = NULL; 00257 new->databuff.k = 0.0; 00258 new->changed = 0; 00259 new->ndims = 0; 00260 new->need_reload = 1; 00261 00262 return (new->data_id); 00263 } 00264 00265 return (-1); 00266 } 00267 00281 typbuff *gsds_get_typbuff(int id, IFLAG change_flag) 00282 { 00283 dataset *ds; 00284 00285 if ((ds = get_dataset(id))) { 00286 ds->changed = ds->changed | change_flag; 00287 ds->need_reload = 0; 00288 00289 return (&(ds->databuff)); 00290 } 00291 00292 return (NULL); 00293 } 00294 00303 char *gsds_get_name(int id) 00304 { 00305 int i; 00306 dataset *fds; 00307 static char retstr[GPATH_MAX]; 00308 00309 for (i = 0; i < Numsets; i++) { 00310 if (Data[i]->data_id == id) { 00311 fds = Data[i]; 00312 strcpy(retstr, fds->unique_name); 00313 00314 return (retstr); 00315 } 00316 } 00317 00318 return (NULL); 00319 } 00320 00329 int gsds_free_datah(int id) 00330 { 00331 int i, j, found = 0; 00332 dataset *fds; 00333 00334 G_debug(3, "gsds_free_datah"); 00335 00336 for (i = 0; i < Numsets; i++) { 00337 if (Data[i]->data_id == id) { 00338 found = 1; 00339 fds = Data[i]; 00340 free_data_buffs(fds, ATTY_ANY); 00341 G_free((void *)fds->unique_name); 00342 fds->unique_name = NULL; 00343 fds->data_id = 0; 00344 00345 for (j = i; j < (Numsets - 1); j++) { 00346 Data[j] = Data[j + 1]; 00347 } 00348 00349 Data[j] = fds; 00350 } 00351 } 00352 00353 if (found) { 00354 --Numsets; 00355 } 00356 00357 return (found); 00358 } 00359 00369 int gsds_free_data_buff(int id, int typ) 00370 { 00371 int i, found = 0; 00372 dataset *fds; 00373 00374 for (i = 0; i < Numsets; i++) { 00375 if (Data[i]->data_id == id) { 00376 found = 1; 00377 fds = Data[i]; 00378 free_data_buffs(fds, typ); 00379 } 00380 } 00381 00382 return (found); 00383 } 00384 00393 int free_data_buffs(dataset * ds, int typ) 00394 { 00395 int nsiz = 1, i, siz, freed = 0; 00396 00397 for (i = 0; i < ds->ndims; i++) { 00398 nsiz *= ds->dims[i]; 00399 } 00400 00401 if (typ & ATTY_NULL) { 00402 if (ds->databuff.nm) { 00403 siz = BM_get_map_size(ds->databuff.nm); 00404 BM_destroy(ds->databuff.nm); 00405 ds->databuff.nm = NULL; 00406 freed += siz; 00407 } 00408 } 00409 00410 if (typ & ATTY_MASK) { 00411 if (ds->databuff.bm) { 00412 siz = BM_get_map_size(ds->databuff.bm); 00413 BM_destroy(ds->databuff.bm); 00414 ds->databuff.bm = NULL; 00415 freed += siz; 00416 } 00417 } 00418 00419 if (typ & ATTY_CHAR) { 00420 if (ds->databuff.cb) { 00421 siz = nsiz * sizeof(char); 00422 free(ds->databuff.cb); 00423 ds->databuff.cb = NULL; 00424 freed += siz; 00425 } 00426 } 00427 00428 if (typ & ATTY_SHORT) { 00429 if (ds->databuff.sb) { 00430 siz = nsiz * sizeof(short); 00431 free(ds->databuff.sb); 00432 ds->databuff.sb = NULL; 00433 freed += siz; 00434 } 00435 } 00436 00437 if (typ & ATTY_INT) { 00438 if (ds->databuff.ib) { 00439 siz = nsiz * sizeof(int); 00440 free(ds->databuff.ib); 00441 ds->databuff.ib = NULL; 00442 freed += siz; 00443 } 00444 } 00445 00446 if (typ & ATTY_FLOAT) { 00447 if (ds->databuff.fb) { 00448 siz = nsiz * sizeof(float); 00449 free(ds->databuff.fb); 00450 ds->databuff.fb = NULL; 00451 freed += siz; 00452 } 00453 } 00454 00455 Tot_mem -= freed; 00456 ds->numbytes -= freed; 00457 00458 if (freed) { 00459 G_debug(5, "free_data_buffs(): freed data from id no. %d", 00460 ds->data_id); 00461 G_debug(5, 00462 "free_data_buffs(): %.3f Kbytes freed, current total = %.3f", 00463 freed / 1000., Tot_mem / 1000.); 00464 } 00465 00466 return (freed); 00467 } 00468 00481 int gsds_alloc_typbuff(int id, int *dims, int ndims, int type) 00482 { 00483 dataset *ds; 00484 int i, siz = 1; 00485 00486 if ((ds = get_dataset(id))) { 00487 /* 00488 free_data_buffs(ds); 00489 careful here - allowing > 1 type to coexist (for float -> color conv.) 00490 now also use this to allocate a null mask 00491 (then if not used, use gsds_free_data_buff(id, ATTY_NULL)) 00492 */ 00493 00494 for (i = 0; i < ndims; i++) { 00495 ds->dims[i] = dims[i]; 00496 siz *= dims[i]; 00497 } 00498 00499 switch (type) { 00500 case ATTY_NULL: 00501 if (ndims != 2) { 00502 /* higher dimension bitmaps not supported */ 00503 return (-1); 00504 } 00505 00506 if (NULL == (ds->databuff.nm = BM_create(dims[1], dims[0]))) { 00507 return (-1); 00508 } 00509 00510 siz = BM_get_map_size(ds->databuff.nm); 00511 00512 break; 00513 00514 case ATTY_MASK: 00515 if (ndims != 2) { 00516 /* higher dimension bitmaps not supported */ 00517 return (-1); 00518 } 00519 00520 if (NULL == (ds->databuff.bm = BM_create(dims[1], dims[0]))) { 00521 return (-1); 00522 } 00523 00524 siz = BM_get_map_size(ds->databuff.bm); 00525 00526 break; 00527 00528 case ATTY_CHAR: 00529 siz *= sizeof(char); 00530 00531 if (siz) { 00532 if (NULL == 00533 (ds->databuff.cb = (unsigned char *)G_malloc(siz))) { 00534 return (-1); 00535 } 00536 } 00537 else { 00538 return (-1); 00539 } 00540 00541 break; 00542 00543 case ATTY_SHORT: 00544 siz *= sizeof(short); 00545 00546 if (siz) { 00547 if (NULL == (ds->databuff.sb = (short *)G_malloc(siz))) { 00548 return (-1); 00549 } 00550 } 00551 else { 00552 return (-1); 00553 } 00554 00555 break; 00556 00557 case ATTY_INT: 00558 siz *= sizeof(int); 00559 00560 if (siz) { 00561 if (NULL == (ds->databuff.ib = (int *)G_malloc(siz))) { 00562 return (-1); 00563 } 00564 } 00565 else { 00566 return (-1); 00567 } 00568 00569 break; 00570 00571 case ATTY_FLOAT: 00572 siz *= sizeof(float); 00573 00574 if (siz) { 00575 if (NULL == (ds->databuff.fb = (float *)G_malloc(siz))) { 00576 return (-1); 00577 } 00578 } 00579 else { 00580 return (-1); 00581 } 00582 00583 break; 00584 00585 default: 00586 return (-1); 00587 } 00588 00589 ds->changed = 0; /* starting with clean slate */ 00590 ds->need_reload = 1; 00591 ds->numbytes += siz; 00592 ds->ndims = ndims; 00593 Tot_mem += siz; 00594 00595 G_debug(5, 00596 "gsds_alloc_typbuff(): %f Kbytes allocated, current total = %f", 00597 siz / 1000., Tot_mem / 1000.); 00598 00599 return (siz); 00600 } 00601 00602 return (-1); 00603 } 00604 00613 int gsds_get_changed(int id) 00614 { 00615 dataset *ds; 00616 00617 if ((ds = get_dataset(id))) { 00618 return ((int)ds->changed); 00619 } 00620 00621 return (-1); 00622 } 00623 00633 int gsds_set_changed(int id, IFLAG reason) 00634 { 00635 dataset *ds; 00636 00637 if ((ds = get_dataset(id))) { 00638 ds->changed = reason; 00639 } 00640 00641 return (-1); 00642 } 00643 00651 int gsds_get_type(int id) 00652 { 00653 dataset *ds; 00654 00655 ds = get_dataset(id); 00656 00657 return (get_type(ds)); 00658 }