gvl_file.c 22 KB

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