gvl_file.c 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183
  1. /*!
  2. \file gvl_file.c
  3. \brief OGSF library - loading and manipulating volumes (lower level functions)
  4. GRASS OpenGL gsurf OGSF Library
  5. (C) 1999-2008 by the GRASS Development Team
  6. This program is free software under the
  7. GNU General Public License (>=v2).
  8. Read the file COPYING that comes with GRASS
  9. for details.
  10. \author Tomas Paudits (February 2004)
  11. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  12. */
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <grass/gis.h>
  16. #include <grass/gstypes.h>
  17. #include <grass/gsurf.h>
  18. #include <grass/G3d.h>
  19. #include <grass/glocale.h>
  20. #define LUCKY 33
  21. #define MODE_DIRECT 0
  22. #define MODE_SLICE 1
  23. #define MODE_FULL 2
  24. #define MODE_PRELOAD 3
  25. #define MODE_DEFAULT 0
  26. #define STATUS_READY 0
  27. #define STATUS_BUSY 1
  28. /*!
  29. \brief structure for slice mode reading from volume file
  30. */
  31. typedef struct
  32. {
  33. int num, skip;
  34. int crnt, base;
  35. void *slice[MAX_VOL_SLICES];
  36. } slice_data;
  37. static geovol_file *Data[MAX_VOL_FILES];
  38. static geovol_file Df[MAX_VOL_FILES]; /* trying to avoid allocation */
  39. static int Numfiles = 0;
  40. static int Cur_id = LUCKY;
  41. static int Cur_max;
  42. static int Rows, Cols, Depths;
  43. /* local functions prototypes */
  44. void *open_g3d_file(const char *, IFLAG *, double *, double *);
  45. int close_g3d_file(void *);
  46. /*!
  47. \brief Initialize volume files
  48. \return 1
  49. */
  50. static int init_volfiles(void)
  51. {
  52. int i;
  53. G3D_Region *w3;
  54. for (i = 0; i < MAX_VOL_FILES; i++) {
  55. /* avoiding dynamic allocation */
  56. Data[i] = &(Df[i]);
  57. }
  58. Cur_max = MAX_VOL_FILES;
  59. /* get window */
  60. w3 = GVL_get_window();
  61. /* set cols, rows, depths from window */
  62. Cols = w3->cols;
  63. Rows = w3->rows;
  64. Depths = w3->depths;
  65. return (1);
  66. }
  67. /*!
  68. \brief Check number of files
  69. \return 0
  70. */
  71. static int check_num_volfiles(void)
  72. {
  73. if (Numfiles < Cur_max) {
  74. return (0);
  75. }
  76. G_fatal_error(_("Maximum number of datafiles exceeded"));
  77. /* This return statement keeps compilers happy, it is never executed */
  78. return (0);
  79. }
  80. /*!
  81. \brief Get geovol_file structure for given handle
  82. \param id
  83. \return pointer to geovol_file struct
  84. \return NULL on failure
  85. */
  86. geovol_file *gvl_file_get_volfile(int id)
  87. {
  88. int i;
  89. for (i = 0; i < Numfiles; i++) {
  90. if (Data[i]->data_id == id) {
  91. return (Data[i]);
  92. }
  93. }
  94. return (NULL);
  95. }
  96. /*!
  97. \brief Find file with name and type in geovol_file array an return handle
  98. \param name file name
  99. \para begin
  100. \param data id
  101. \param -1 not found
  102. */
  103. int find_datah(const char *name, IFLAG type, int begin)
  104. {
  105. static int i;
  106. int start;
  107. start = begin ? 0 : i + 1;
  108. for (i = start; i < Numfiles; i++) {
  109. if (!strcmp(Data[i]->file_name, name)) {
  110. if (Data[i]->file_type == type) {
  111. return (Data[i]->data_id);
  112. }
  113. }
  114. }
  115. return (-1);
  116. }
  117. /*!
  118. \brief Get file name for given handle
  119. \param id handle id
  120. \return file name
  121. \return NULL on failure
  122. */
  123. char *gvl_file_get_name(int id)
  124. {
  125. int i;
  126. geovol_file *fvf;
  127. static char retstr[GPATH_MAX];
  128. for (i = 0; i < Numfiles; i++) {
  129. if (Data[i]->data_id == id) {
  130. fvf = Data[i];
  131. strcpy(retstr, fvf->file_name);
  132. return (retstr);
  133. }
  134. }
  135. return (NULL);
  136. }
  137. /*!
  138. \brief Get file type for given handle
  139. \param vf pointer to geovol_file struct
  140. \return file type
  141. */
  142. int gvl_file_get_file_type(geovol_file * vf)
  143. {
  144. return (vf->file_type);
  145. }
  146. /*!
  147. \brief Get data type for given handle
  148. \param vf pointer to geovol_file struct
  149. \return data type
  150. */
  151. int gvl_file_get_data_type(geovol_file * vf)
  152. {
  153. return (vf->data_type);
  154. }
  155. /*!
  156. \brief Get minimum and maximum value in volume file
  157. \param vf pointer to geovol_file struct
  158. \param[out] min min value
  159. \param[out] max max value
  160. */
  161. void gvl_file_get_min_max(geovol_file * vf, double *min, double *max)
  162. {
  163. *min = vf->min;
  164. *max = vf->max;
  165. }
  166. /*!
  167. \brief Open 3d raster file
  168. \param name file name
  169. \param file_type file type
  170. \param data_type data type
  171. \param[out] min min value
  172. \param[out] max max value
  173. \return pointer to file
  174. \return NULL on failure
  175. */
  176. void *open_volfile(const char *name, IFLAG file_type, IFLAG * data_type,
  177. double *min, double *max)
  178. {
  179. if (file_type == VOL_FTYPE_G3D) {
  180. return open_g3d_file(name, data_type, min, max);
  181. }
  182. return (NULL);
  183. }
  184. /*!
  185. \brief Close volume file
  186. \param map volume filename
  187. \param type file type
  188. \return
  189. \return -1 on failure
  190. */
  191. int close_volfile(void *map, IFLAG type)
  192. {
  193. if (type == VOL_FTYPE_G3D) {
  194. return close_g3d_file(map);
  195. }
  196. return (-1);
  197. }
  198. /*!
  199. \brief Get handle for given file name and type
  200. \param name volume filename
  201. \param file_type file type
  202. \return data id
  203. \return -1 on failure
  204. */
  205. int gvl_file_newh(const char *name, IFLAG file_type)
  206. {
  207. geovol_file *new;
  208. static int first = 1;
  209. int i, id;
  210. void *m;
  211. IFLAG data_type;
  212. double min, max;
  213. if (first) {
  214. if (0 > init_volfiles()) {
  215. return (-1);
  216. }
  217. first = 0;
  218. }
  219. if (0 <= (id = find_datah(name, file_type, 1))) {
  220. for (i = 0; i < Numfiles; i++) {
  221. if (Data[i]->data_id == id) {
  222. new = Data[i];
  223. new->count++;
  224. return (id);
  225. }
  226. }
  227. }
  228. if (0 > check_num_volfiles()) {
  229. return (-1);
  230. }
  231. if (!name) {
  232. return (-1);
  233. }
  234. if ((m = open_volfile(name, file_type, &data_type, &min, &max)) == NULL) {
  235. return (-1);
  236. }
  237. new = Data[Numfiles];
  238. if (new) {
  239. Numfiles++;
  240. new->data_id = Cur_id++;
  241. new->file_name = G_store(name);
  242. new->file_type = file_type;
  243. new->count = 1;
  244. new->map = m;
  245. new->min = min;
  246. new->max = max;
  247. new->data_type = data_type;
  248. new->status = STATUS_READY;
  249. new->buff = NULL;
  250. new->mode = 255;
  251. gvl_file_set_mode(new, MODE_DEFAULT);
  252. return (new->data_id);
  253. }
  254. return (-1);
  255. }
  256. /*!
  257. \brief Free allocated buffers
  258. \param vf pointer to geovol_file struct
  259. \return 1
  260. */
  261. int free_volfile_buffs(geovol_file * vf)
  262. {
  263. if (vf->mode == MODE_SLICE) {
  264. G_free(vf->buff);
  265. vf->buff = NULL;
  266. }
  267. if (vf->mode == MODE_PRELOAD) {
  268. G_free(vf->buff);
  269. vf->buff = NULL;
  270. }
  271. return (1);
  272. }
  273. /*!
  274. \brief Free geovol_file structure for given handle
  275. \param id
  276. \return
  277. */
  278. int gvl_file_free_datah(int id)
  279. {
  280. int i, j, found = -1;
  281. geovol_file *fvf;
  282. G_debug(5, "gvl_file_free_datah(): id=%d", id);
  283. for (i = 0; i < Numfiles; i++) {
  284. if (Data[i]->data_id == id) {
  285. found = 1;
  286. fvf = Data[i];
  287. if (fvf->count > 1) {
  288. fvf->count--;
  289. }
  290. else {
  291. close_volfile(fvf->map, fvf->file_type);
  292. free_volfile_buffs(fvf);
  293. G_free(fvf->file_name);
  294. fvf->file_name = NULL;
  295. fvf->data_id = 0;
  296. for (j = i; j < (Numfiles - 1); j++) {
  297. Data[j] = Data[j + 1];
  298. }
  299. Data[j] = fvf;
  300. --Numfiles;
  301. }
  302. }
  303. }
  304. return (found);
  305. }
  306. /******************************************************************/
  307. /* reading from G3D raster volume files */
  308. /******************************************************************/
  309. /*!
  310. \brief Open 3d raster file
  311. \param filename file name
  312. \param type data type
  313. \param[out] min min value
  314. \param[out] max max value
  315. \pointer to data
  316. */
  317. void *open_g3d_file(const char *filename, IFLAG * type, double *min,
  318. double *max)
  319. {
  320. const char *mapset;
  321. int itype;
  322. void *map;
  323. /* search for g3d file a return his mapset */
  324. mapset = G_find_grid3(filename, "");
  325. if (!mapset) {
  326. G_warning(_("3D raster map <%s> not found"), filename);
  327. return (NULL);
  328. }
  329. /* open g3d file */
  330. map =
  331. G3d_openCellOld(filename, mapset, G3D_DEFAULT_WINDOW,
  332. G3D_TILE_SAME_AS_FILE, G3D_USE_CACHE_DEFAULT);
  333. if (!map) {
  334. G_warning(_("Unable to open 3D raster map <%s>"), filename);
  335. return (NULL);
  336. }
  337. /* load range into range structure of map */
  338. if (!G3d_range_load(map)) {
  339. G_warning(_("Unable to read range of 3D raster map <%s>"), filename);
  340. return (NULL);
  341. }
  342. G3d_range_min_max(map, min, max);
  343. /* get file data type */
  344. itype = G3d_fileTypeMap(map);
  345. if (itype == FCELL_TYPE)
  346. *type = VOL_DTYPE_FLOAT;
  347. if (itype == DCELL_TYPE)
  348. *type = VOL_DTYPE_DOUBLE;
  349. return (map);
  350. }
  351. /*!
  352. \brief Close g3d file
  353. \param map 3d raster map
  354. \return -1 on failure
  355. \return 1 on success
  356. */
  357. int close_g3d_file(void *map)
  358. {
  359. /* close opened g3d file */
  360. if (G3d_closeCell((G3D_Map *) map) != 1) {
  361. G_warning(_("Unable to close 3D raster map <%s>"),
  362. ((G3D_Map *) map)->fileName);
  363. return (-1);
  364. }
  365. return (1);
  366. }
  367. /*!
  368. \brief Eead value from g3d file
  369. \param type data type
  370. \param map 3D raster map
  371. \param x,y,z real coordinates
  372. \param[out] value data value
  373. \return -1 on failure
  374. \return 1 on success
  375. */
  376. int read_g3d_value(IFLAG type, void *map, int x, int y, int z, void *value)
  377. {
  378. switch (type) {
  379. /* float data type */
  380. case (VOL_DTYPE_FLOAT):
  381. *((float *)value) = G3d_getFloat(map, x, y, z);
  382. break;
  383. /* double data type */
  384. case (VOL_DTYPE_DOUBLE):
  385. *((double *)value) = G3d_getDouble(map, x, y, z);
  386. break;
  387. /* unsupported data type */
  388. default:
  389. return (-1);
  390. }
  391. return (1);
  392. }
  393. /*!
  394. \brief Read slice of values at level from g3d file
  395. \param type data type
  396. \param map 3D raster map
  397. \param level
  398. \param[out] data
  399. \return -1 on failure
  400. \return 0 on success
  401. */
  402. int read_g3d_slice(IFLAG type, void *map, int level, void *data)
  403. {
  404. int x, y;
  405. switch (type) {
  406. /* float data type */
  407. case (VOL_DTYPE_FLOAT):
  408. for (x = 0; x < Cols; x++) {
  409. for (y = 0; y < Rows; y++) {
  410. ((float *)data)[x + y * Cols] =
  411. G3d_getFloat(map, x, y, level);
  412. }
  413. }
  414. break;
  415. /* double data type */
  416. case (VOL_DTYPE_DOUBLE):
  417. for (x = 0; x < Cols; x++) {
  418. for (y = 0; y < Rows; y++) {
  419. ((double *)data)[x + y * Cols] =
  420. G3d_getDouble(map, x, y, level);
  421. }
  422. }
  423. break;
  424. /* unsupported data type */
  425. default:
  426. return (-1);
  427. }
  428. return (1);
  429. }
  430. /*!
  431. \brief Read all values from g3d file
  432. \param type data type
  433. \param map 3D raster map
  434. \param[out] data data buffer
  435. \return -1 on failure
  436. \return 1 on success
  437. */
  438. int read_g3d_vol(IFLAG type, void *map, void *data)
  439. {
  440. int x, y, z;
  441. switch (type) {
  442. /* float data type */
  443. case (VOL_DTYPE_FLOAT):
  444. for (x = 0; x < Cols; x++) {
  445. for (y = 0; y < Rows; y++) {
  446. for (z = 0; z < Depths; z++) {
  447. ((float *)data)[x + y * Cols + z * Rows * Cols] =
  448. G3d_getFloat(map, x, y, z);
  449. }
  450. }
  451. }
  452. break;
  453. /* double data type */
  454. case (VOL_DTYPE_DOUBLE):
  455. for (x = 0; x < Cols; x++) {
  456. for (y = 0; y < Rows; y++) {
  457. for (z = 0; z < Depths; z++) {
  458. ((double *)data)[x + y * Cols + z * Rows * Cols] =
  459. G3d_getDouble(map, x, y, z);
  460. }
  461. }
  462. }
  463. break;
  464. /* unsupported data type */
  465. default:
  466. return (-1);
  467. }
  468. return (1);
  469. }
  470. /*!
  471. \brief Check for null value
  472. \param type data type
  473. \param value
  474. \return 1 if value is null
  475. \return 0 if value is not null
  476. \return -1 on failure (unsupported data type
  477. */
  478. int is_null_g3d_value(IFLAG type, void *value)
  479. {
  480. switch (type) {
  481. /* float data type */
  482. case (VOL_DTYPE_FLOAT):
  483. return G3d_isNullValueNum(value, FCELL_TYPE);
  484. break;
  485. /* double data type */
  486. case (VOL_DTYPE_DOUBLE):
  487. return G3d_isNullValueNum(value, DCELL_TYPE);
  488. break;
  489. /* unsupported data type */
  490. default:
  491. return (-1);
  492. }
  493. return (-1);
  494. }
  495. /******************************************************************/
  496. /* reading from buffer */
  497. /******************************************************************/
  498. /*!
  499. \brief Get value from buffer
  500. \param type data type
  501. \param data data buffer
  502. \param offset
  503. \param value
  504. \return -1 on failure (unsupported data type)
  505. \return 1 on success
  506. */
  507. int get_buff_value(IFLAG type, void *data, int offset, void *value)
  508. {
  509. switch (type) {
  510. /* float data type */
  511. case (VOL_DTYPE_FLOAT):
  512. *((float *)value) = ((float *)data)[offset];
  513. break;
  514. /* double data type */
  515. case (VOL_DTYPE_DOUBLE):
  516. *((double *)value) = ((double *)data)[offset];
  517. break;
  518. /* unsupported data type */
  519. default:
  520. return (-1);
  521. }
  522. return (1);
  523. }
  524. /******************************************************************/
  525. /* direct mode reading from volume file */
  526. /******************************************************************/
  527. /*!
  528. \brief Read value direct from volume file
  529. \param vf pointer to geovol_file struct
  530. \param x,y,z real point
  531. \oaram[out] value data value
  532. \return -1 on failure
  533. \return 1 on success
  534. */
  535. int get_direct_value(geovol_file * vf, int x, int y, int z, void *value)
  536. {
  537. switch (vf->file_type) {
  538. /* G3D file type */
  539. case (VOL_FTYPE_G3D):
  540. if (0 > read_g3d_value(vf->data_type, vf->map, x, y, z, value))
  541. return (-1);
  542. break;
  543. default:
  544. return (-1);
  545. }
  546. return (1);
  547. }
  548. /******************************************************************/
  549. /* full mode reading from volume file */
  550. /******************************************************************/
  551. /*!
  552. \brief Allocate buffer memory for full mode reading
  553. \param vf pointer to geovol_file
  554. \return -1 on failure
  555. \return 1 on success
  556. */
  557. int alloc_vol_buff(geovol_file * vf)
  558. {
  559. switch (vf->data_type) {
  560. /* float data type */
  561. case (VOL_DTYPE_FLOAT):
  562. if ((vf->buff =
  563. (float *)G_malloc(sizeof(float) * Cols * Rows * Depths)) == NULL)
  564. return (-1);
  565. break;
  566. /* double data type */
  567. case (VOL_DTYPE_DOUBLE):
  568. if ((vf->buff =
  569. (double *)G_malloc(sizeof(double) * Cols * Rows * Depths)) ==
  570. NULL)
  571. return (-1);
  572. break;
  573. /* unsupported data type */
  574. default:
  575. return (-1);
  576. }
  577. return (1);
  578. }
  579. /*!
  580. \brief Free memory buffer memory
  581. \param vf pointer to geovol_file struct
  582. \return 1
  583. */
  584. int free_vol_buff(geovol_file * vf)
  585. {
  586. G_free(vf->buff);
  587. return (1);
  588. }
  589. /*!
  590. \brief Read all values from volume file
  591. \param vf pointer to geovol_file struct
  592. \return -1 on failure
  593. \return 1 on success
  594. */
  595. int read_vol(geovol_file * vf)
  596. {
  597. switch (vf->file_type) {
  598. /* G3D file format */
  599. case (VOL_FTYPE_G3D):
  600. if (0 > read_g3d_vol(vf->data_type, vf->map, vf->buff))
  601. return (-1);
  602. break;
  603. /* unsupported file format */
  604. default:
  605. return (-1);
  606. }
  607. return (1);
  608. }
  609. /*!
  610. \brief Get value from volume buffer
  611. \param vf pointer to geovol_file struct
  612. \param x,y,z real point
  613. \param[out] value data value
  614. \return 1
  615. */
  616. int get_vol_value(geovol_file * vf, int x, int y, int z, void *value)
  617. {
  618. get_buff_value(vf->data_type, vf->buff, z * Rows * Cols + y * Cols + x,
  619. value);
  620. return (1);
  621. }
  622. /******************************************************************/
  623. /* slice mode reading from volume file */
  624. /******************************************************************/
  625. /*!
  626. \brief Allocate buffer for slice mode reading
  627. \param vf pointer to geovol_file struct
  628. \return -1 on failure
  629. \return 1 on success
  630. */
  631. int alloc_slice_buff(geovol_file * vf)
  632. {
  633. int i;
  634. slice_data *sd = (slice_data *) vf->buff;
  635. switch (vf->data_type) {
  636. /* float data type */
  637. case (VOL_DTYPE_FLOAT):
  638. for (i = 0; i < sd->num; i++) {
  639. if ((sd->slice[i] =
  640. (float *)G_malloc(sizeof(float) * Cols * Rows)) == NULL)
  641. return (-1);
  642. }
  643. break;
  644. /* double data type */
  645. case (VOL_DTYPE_DOUBLE):
  646. for (i = 0; i < sd->num; i++) {
  647. if ((sd->slice[i] =
  648. (double *)G_malloc(sizeof(double) * Cols * Rows)) == NULL)
  649. return (-1);
  650. }
  651. break;
  652. /* unsupported data type */
  653. default:
  654. return (-1);
  655. }
  656. return (1);
  657. }
  658. /*!
  659. \brief Free buffer for slice mode reading
  660. \param vf pointer to geovol_file struct
  661. \return 1
  662. */
  663. int free_slice_buff(geovol_file * vf)
  664. {
  665. int i;
  666. slice_data *sd = (slice_data *) vf->buff;
  667. for (i = 0; i < sd->num; i++) {
  668. G_free(sd->slice[i]);
  669. }
  670. return (1);
  671. }
  672. /*!
  673. \brief Read slice of values at level from volume file
  674. \param vf pointer to geovol_file struct
  675. \param s
  676. \param l
  677. \return -1 on failure
  678. \return 1 on success
  679. */
  680. int read_slice(geovol_file * vf, int s, int l)
  681. {
  682. /* get slice structure */
  683. slice_data *sd = (slice_data *) vf->buff;
  684. switch (vf->file_type) {
  685. /* G3D file format */
  686. case (VOL_FTYPE_G3D):
  687. if (0 > read_g3d_slice(vf->data_type, vf->map, l, sd->slice[s]))
  688. return (-1);
  689. break;
  690. /* unsupported file format */
  691. default:
  692. return (-1);
  693. }
  694. return (1);
  695. }
  696. /*!
  697. \brief Read new slice into buffer
  698. \param vf pointer to geovol_file struct
  699. */
  700. void shift_slices(geovol_file * vf)
  701. {
  702. void *tmp;
  703. int i;
  704. slice_data *sd = (slice_data *) vf->buff;
  705. /* change pointers to slices */
  706. tmp = sd->slice[0];
  707. for (i = 0; i < sd->num - 1; i++) {
  708. sd->slice[i] = sd->slice[i + 1];
  709. }
  710. sd->slice[sd->num - 1] = tmp;
  711. /* read new slice data */
  712. read_slice(vf, sd->num, sd->crnt + 1 + (sd->num - sd->base));
  713. /* increase current slice value */
  714. sd->crnt++;
  715. }
  716. /*!
  717. \brief Get value from slice buffer
  718. \param vf pointer to geovol_file struct
  719. \param x,y,z real point
  720. \param[out] value data value
  721. \return -1 on failure
  722. \return 1 on success
  723. */
  724. int get_slice_value(geovol_file * vf, int x, int y, int z, void *value)
  725. {
  726. slice_data *sd = (slice_data *) vf->buff;
  727. /* value is in loaded slices */
  728. if ((z >= sd->crnt - (sd->base - 1)) &&
  729. (z <= sd->crnt + sd->num - sd->base)) {
  730. get_buff_value(vf->data_type, sd->slice[(z - sd->crnt)], y * Cols + x,
  731. value);
  732. }
  733. /* if value isn't in loaded slices, need read new data slice */
  734. else if (z == sd->crnt - (sd->base - 1) + 1) {
  735. shift_slices(vf);
  736. get_buff_value(vf->data_type, sd->slice[(z - sd->crnt)], y * Cols + x,
  737. value);
  738. }
  739. /* value out of range */
  740. else {
  741. return (-1);
  742. }
  743. return (1);
  744. }
  745. /******************************************************************/
  746. /* reading from volume file */
  747. /******************************************************************/
  748. /*!
  749. \brief Start read - allocate memory buffer a read first data into buffer
  750. \param vf pointer to geovol_file struct
  751. \return -1 on failure
  752. \return 1 on success
  753. */
  754. int gvl_file_start_read(geovol_file * vf)
  755. {
  756. int i;
  757. slice_data *sd;
  758. /* check status */
  759. if (vf->status == STATUS_BUSY)
  760. return (-1);
  761. switch (vf->mode) {
  762. /* read whole volume into memory */
  763. case (MODE_FULL):
  764. /* allocate memory */
  765. if (0 > alloc_vol_buff(vf))
  766. return (-1);
  767. /* read volume */
  768. read_vol(vf);
  769. break;
  770. /* read first data slices into memory */
  771. case (MODE_SLICE):
  772. /* allocate slices buffer memory */
  773. if (0 > alloc_slice_buff(vf))
  774. return (-1);
  775. /* read volume */
  776. sd = (slice_data *) vf->buff;
  777. /* set current slice to 0 */
  778. sd->crnt = 0;
  779. /* read first slices into buffer */
  780. for (i = 0; i < (sd->num - sd->base + 1); i++)
  781. read_slice(vf, (sd->base - 1) + i, i);
  782. break;
  783. }
  784. /* set status */
  785. vf->status = STATUS_BUSY;
  786. return (1);
  787. }
  788. /*!
  789. \brief End read - free buffer memory
  790. \param vf pointer to geovol_file struct
  791. \return -1 on failure
  792. \return 1 on success
  793. */
  794. int gvl_file_end_read(geovol_file * vf)
  795. {
  796. /* check status */
  797. if (vf->status == STATUS_READY)
  798. return (-1);
  799. switch (vf->mode) {
  800. case (MODE_FULL):
  801. if (0 > free_vol_buff(vf))
  802. return (-1);
  803. break;
  804. case (MODE_SLICE):
  805. /* allocate slices buffer memory */
  806. if (0 > free_slice_buff(vf))
  807. return (-1);
  808. }
  809. /* set status */
  810. vf->status = STATUS_READY;
  811. return (1);
  812. }
  813. /*!
  814. \brief Get value for volume file at x, y, z
  815. \param vf pointer to geovol_file struct
  816. \return -1 on failure
  817. \return 1 on success
  818. */
  819. int gvl_file_get_value(geovol_file * vf, int x, int y, int z, void *value)
  820. {
  821. /* check status */
  822. if (vf->status != STATUS_BUSY) {
  823. return (-1);
  824. }
  825. switch (vf->mode) {
  826. /* read value direct from g3d file */
  827. case (MODE_DIRECT):
  828. if (0 > get_direct_value(vf, x, y, z, value))
  829. return (-1);
  830. break;
  831. case (MODE_SLICE):
  832. if (0 > get_slice_value(vf, x, y, z, value))
  833. return (-1);
  834. break;
  835. case (MODE_FULL):
  836. case (MODE_PRELOAD):
  837. if (0 > get_vol_value(vf, x, y, z, value))
  838. return (-1);
  839. break;
  840. }
  841. return (1);
  842. }
  843. /*!
  844. \brief Check for null value
  845. \param vf pointer to geovol_file struct
  846. \param value data value
  847. \return -1 on failure
  848. \return 1 on success
  849. */
  850. int gvl_file_is_null_value(geovol_file * vf, void *value)
  851. {
  852. switch (vf->file_type) {
  853. /* G3D file format */
  854. case (VOL_FTYPE_G3D):
  855. return is_null_g3d_value(vf->file_type, value);
  856. break;
  857. /* unsupported file format */
  858. default:
  859. return (-1);
  860. }
  861. return (-1);
  862. }
  863. /******************************************************************/
  864. /* set parameters for reading volumes */
  865. /******************************************************************/
  866. /*!
  867. \brief Set read mode
  868. \param vf pointer to geovol_file struct
  869. \param mode read mode
  870. \return -1 on failure
  871. \return 1 on success
  872. */
  873. int gvl_file_set_mode(geovol_file * vf, IFLAG mode)
  874. {
  875. slice_data *sd;
  876. if (vf->status == STATUS_BUSY)
  877. return (-1);
  878. if (vf->mode == mode)
  879. return (1);
  880. if (vf->mode == MODE_SLICE)
  881. G_free(vf->buff);
  882. if (vf->mode == MODE_PRELOAD)
  883. G_free(vf->buff);
  884. if (mode == MODE_SLICE) {
  885. if ((vf->buff = (slice_data *) G_malloc(sizeof(slice_data))) == NULL)
  886. return (-1);
  887. sd = (slice_data *) vf->buff;
  888. sd->num = 1;
  889. sd->crnt = 0;
  890. sd->base = 1;
  891. }
  892. if (mode == MODE_PRELOAD) {
  893. /* allocate memory */
  894. if (0 > alloc_vol_buff(vf))
  895. return (-1);
  896. /* read volume */
  897. read_vol(vf);
  898. }
  899. vf->mode = mode;
  900. return (1);
  901. }
  902. /*!
  903. \brief Set parameters for slice reading
  904. \param vf pointer to geovol_file struct
  905. \param n
  906. \param b
  907. \return -1 on failure
  908. \return 1 on success
  909. */
  910. int gvl_file_set_slices_param(geovol_file * vf, int n, int b)
  911. {
  912. slice_data *sd;
  913. if (vf->status == STATUS_BUSY)
  914. return (-1);
  915. if (!(vf->mode == MODE_SLICE))
  916. return (-1);
  917. sd = (slice_data *) vf->buff;
  918. sd->num = n;
  919. sd->base = b;
  920. return (1);
  921. }