tilewrite.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>
  5. #include <rpc/types.h>
  6. #include <rpc/xdr.h>
  7. #include <grass/raster.h>
  8. #include "G3d_intern.h"
  9. /*---------------------------------------------------------------------------*/
  10. static int
  11. G3d_tile2xdrTile(G3D_Map * map, const void *tile, int rows, int cols,
  12. int depths, int xRedundant, int yRedundant, int zRedundant,
  13. int nofNum, int type)
  14. {
  15. int y, z;
  16. if (!G3d_initCopyToXdr(map, type)) {
  17. G3d_error("G3d_tile2xdrTile: error in G3d_initCopyToXdr");
  18. return 0;
  19. }
  20. if (nofNum == map->tileSize) {
  21. if (!G3d_copyToXdr(tile, map->tileSize)) {
  22. G3d_error("G3d_tile2xdrTile: error in G3d_copyToXdr");
  23. return 0;
  24. }
  25. return 1;
  26. }
  27. if (xRedundant) {
  28. for (z = 0; z < depths; z++) {
  29. for (y = 0; y < rows; y++) {
  30. if (!G3d_copyToXdr(tile, cols)) {
  31. G3d_error("G3d_tile2xdrTile: error in G3d_copyToXdr");
  32. return 0;
  33. }
  34. tile = G_incr_void_ptr(tile, map->tileX * G3d_length(type));
  35. }
  36. if (yRedundant)
  37. tile =
  38. G_incr_void_ptr(tile,
  39. map->tileX * yRedundant *
  40. G3d_length(type));
  41. }
  42. return 1;
  43. }
  44. if (yRedundant) {
  45. for (z = 0; z < depths; z++) {
  46. if (!G3d_copyToXdr(tile, map->tileX * rows)) {
  47. G3d_error("G3d_tile2xdrTile: error in G3d_copyToXdr");
  48. return 0;
  49. }
  50. tile = G_incr_void_ptr(tile, map->tileXY * G3d_length(type));
  51. }
  52. return 1;
  53. }
  54. if (!G3d_copyToXdr(tile, map->tileXY * depths)) {
  55. G3d_error("G3d_tile2xdrTile: error in G3d_copyToXdr");
  56. return 0;
  57. }
  58. return 1;
  59. }
  60. /*---------------------------------------------------------------------------*/
  61. static int G3d_writeTileUncompressed(G3D_Map * map, int nofNum)
  62. {
  63. if (write(map->data_fd, xdr, map->numLengthExtern * nofNum) !=
  64. map->numLengthExtern * nofNum) {
  65. G3d_error("G3d_writeTileUncompressed: can't write file.");
  66. return 0;
  67. }
  68. return 1;
  69. }
  70. /*---------------------------------------------------------------------------*/
  71. static int G3d_writeTileCompressed(G3D_Map * map, int nofNum)
  72. {
  73. if (!G_fpcompress_writeXdrNums(map->data_fd, xdr, nofNum, map->precision,
  74. tmpCompress, map->type == FCELL_TYPE,
  75. map->useRle, map->useLzw)) {
  76. G3d_error
  77. ("G3d_writeTileCompressed: error in G_fpcompress_writeXdrNums");
  78. return 0;
  79. }
  80. return 1;
  81. }
  82. /*---------------------------------------------------------------------------*/
  83. /*---------------------------------------------------------------------------*/
  84. /* EXPORTED FUNCTIONS */
  85. /*---------------------------------------------------------------------------*/
  86. /*---------------------------------------------------------------------------*/
  87. /*!
  88. * \brief
  89. *
  90. *
  91. * Writes tile with index <em>tileIndex</em> to the file corresponding to <em>map</em>.
  92. * It is assumed that the cells in <em>tile</em> are of <em>type</em> which
  93. * must be one of FCELL_TYPE and DCELL_TYPE. The actual type used to write the
  94. * tile depends on the type specified at the time when <em>map</em> is initialized.
  95. * A tile can only be written once. Subsequent attempts to write the same tile
  96. * are ignored.
  97. *
  98. * \param map
  99. * \param tileIndex
  100. * \param tile
  101. * \param type
  102. * \return 1 ... if successful,
  103. * 2 ... if write request was ignored,
  104. * 0 ... otherwise.
  105. */
  106. int G3d_writeTile(G3D_Map * map, int tileIndex, const void *tile, int type)
  107. {
  108. int rows, cols, depths, xRedundant, yRedundant, zRedundant, nofNum;
  109. /* valid tileIndex ? */
  110. if ((tileIndex >= map->nTiles) || (tileIndex < 0))
  111. G3d_fatalError("G3d_writeTile: tileIndex out of range");
  112. /* already written ? */
  113. if (map->index[tileIndex] != -1)
  114. return 2;
  115. /* save the file position */
  116. map->index[tileIndex] = lseek(map->data_fd, (long)0, SEEK_END);
  117. if (map->index[tileIndex] == -1) {
  118. G3d_error("G3d_writeTile: can't position file");
  119. return 0;
  120. }
  121. nofNum = G3d_computeClippedTileDimensions(map, tileIndex,
  122. &rows, &cols, &depths,
  123. &xRedundant, &yRedundant,
  124. &zRedundant);
  125. G3d_range_updateFromTile(map, tile, rows, cols, depths,
  126. xRedundant, yRedundant, zRedundant, nofNum,
  127. type);
  128. if (!G3d_tile2xdrTile(map, tile, rows, cols, depths,
  129. xRedundant, yRedundant, zRedundant, nofNum, type)) {
  130. G3d_error("G3d_writeTileCompressed: error in G3d_tile2xdrTile");
  131. return 0;
  132. }
  133. if (map->compression == G3D_NO_COMPRESSION) {
  134. if (!G3d_writeTileUncompressed(map, nofNum)) {
  135. G3d_error("G3d_writeTile: error in G3d_writeTileUncompressed");
  136. return 0;
  137. }
  138. }
  139. else if (!G3d_writeTileCompressed(map, nofNum)) {
  140. G3d_error("G3d_writeTile: error in G3d_writeTileCompressed");
  141. return 0;
  142. }
  143. /* compute the length */
  144. map->tileLength[tileIndex] = lseek(map->data_fd, (long)0, SEEK_END) -
  145. map->index[tileIndex];
  146. return 1;
  147. }
  148. /*---------------------------------------------------------------------------*/
  149. /*!
  150. * \brief
  151. *
  152. * Is equivalent to <tt>G3d_writeTile (map, tileIndex, tile, FCELL_TYPE).</tt>
  153. *
  154. * \param map
  155. * \param tileIndex
  156. * \param tile
  157. * \return int
  158. */
  159. int G3d_writeTileFloat(G3D_Map * map, int tileIndex, const void *tile)
  160. {
  161. int status;
  162. if ((status = G3d_writeTile(map, tileIndex, tile, FCELL_TYPE)))
  163. return status;
  164. G3d_error("G3d_writeTileFloat: error in G3d_writeTile");
  165. return 0;
  166. }
  167. /*---------------------------------------------------------------------------*/
  168. /*!
  169. * \brief
  170. *
  171. * Is equivalent to <tt>G3d_writeTile (map, tileIndex, tile, DCELL_TYPE).</tt>
  172. *
  173. * \param map
  174. * \param tileIndex
  175. * \param tile
  176. * \return int
  177. */
  178. int G3d_writeTileDouble(G3D_Map * map, int tileIndex, const void *tile)
  179. {
  180. int status;
  181. if ((status = G3d_writeTile(map, tileIndex, tile, DCELL_TYPE)))
  182. return status;
  183. G3d_error("G3d_writeTileDouble: error in G3d_writeTile");
  184. return 0;
  185. }
  186. /*---------------------------------------------------------------------------*/
  187. /* CACHE-MODE-ONLY FUNCTIONS */
  188. /*---------------------------------------------------------------------------*/
  189. /*!
  190. * \brief
  191. *
  192. * Writes the tile with
  193. * <em>tileIndex</em> to the file corresponding to <em>map</em> and removes the tile
  194. * from the cache (in non-cache mode the buffer provided by the map-structure is
  195. * written).
  196. * If this tile has already been written before the write request is ignored.
  197. * If the tile was never referred to before the invokation of G3d_flushTile, a
  198. * tile filled with NULL-values is written.
  199. *
  200. * \param map
  201. * \param tileIndex
  202. * \return 1 ... if successful,
  203. * 0 ... otherwise.
  204. */
  205. int G3d_flushTile(G3D_Map * map, int tileIndex)
  206. {
  207. const void *tile;
  208. tile = G3d_getTilePtr(map, tileIndex);
  209. if (tile == NULL) {
  210. G3d_error("G3d_flushTile: error in G3d_getTilePtr");
  211. return 0;
  212. }
  213. if (!G3d_writeTile(map, tileIndex, tile, map->typeIntern)) {
  214. G3d_error("G3d_flushTile: error in G3d_writeTile");
  215. return 0;
  216. }
  217. if (!G3d__removeTile(map, tileIndex)) {
  218. G3d_error("G3d_flushTile: error in G3d__removeTile");
  219. return 0;
  220. }
  221. return 1;
  222. }
  223. /*---------------------------------------------------------------------------*/
  224. #ifndef MIN
  225. #define MIN(a,b) (a < b ? a : b)
  226. #define MAX(a,b) (a > b ? a : b)
  227. #endif
  228. /*!
  229. * \brief
  230. *
  231. * Writes the tiles with tile-coordinates
  232. * contained in the axis-parallel cube with vertices <em>(xMin, yMin, zMin)</em>
  233. * and <em>(xMax, yMax, zMax</em>). Tiles which are not stored in the cache are
  234. * written as NULL-tiles. Write attempts for tiles which have already been
  235. * written earlier are ignored.
  236. *
  237. * \param map
  238. * \param xMin
  239. * \param yMin
  240. * \param zMin
  241. * \param xMax
  242. * \param yMax
  243. * \param zMax
  244. * \return 1 ... if successful,
  245. * 0 ... otherwise.
  246. */
  247. int
  248. G3d_flushTileCube(G3D_Map * map, int xMin, int yMin, int zMin, int xMax,
  249. int yMax, int zMax)
  250. {
  251. int x, y, z;
  252. if (!map->useCache)
  253. G3d_fatalError
  254. ("G3d_flushTileCube: function invalid in non-cache mode");
  255. for (x = xMin; x <= xMax; x++)
  256. for (y = yMin; y <= yMax; y++)
  257. for (z = zMin; z <= zMax; z++)
  258. if (!G3d_flushTile(map, G3d_tile2tileIndex(map, x, y, z))) {
  259. G3d_error("G3d_flushTileCube: error in G3d_flushTile");
  260. return 0;
  261. }
  262. return 1;
  263. }
  264. /*---------------------------------------------------------------------------*/
  265. /*!
  266. * \brief
  267. *
  268. * Writes those tiles for which
  269. * <em>every</em> cell has coordinate contained in the axis-parallel cube
  270. * defined by the vertices with cell-coordinates <em>(xMin, yMin, zMin)</em>
  271. * and <em>(xMax, yMax, zMax)</em>.
  272. * Tiles which are not stored in the cache are written as NULL-tiles.
  273. * Write attempts for tiles which have already been written earlier are
  274. * ignored.
  275. *
  276. * \param map
  277. * \param xMin
  278. * \param yMin
  279. * \param zMin
  280. * \param xMax
  281. * \param yMax
  282. * \param zMax
  283. * \return 1 ... if successful,
  284. * 0 ... otherwise.
  285. */
  286. int
  287. G3d_flushTilesInCube(G3D_Map * map, int xMin, int yMin, int zMin, int xMax,
  288. int yMax, int zMax)
  289. {
  290. int xTileMin, yTileMin, zTileMin, xTileMax, yTileMax, zTileMax;
  291. int xOffs, yOffs, zOffs;
  292. int regionMaxX, regionMaxY, regionMaxZ;
  293. if (!map->useCache)
  294. G3d_fatalError
  295. ("G3d_flushTilesInCube: function invalid in non-cache mode");
  296. /*AV*/
  297. /*BEGIN OF ORIGINAL CODE */
  298. /*
  299. * G3d_getCoordsMap (map, &regionMaxX, &regionMaxY, &regionMaxZ);
  300. */
  301. /*AV*/
  302. /* BEGIN OF MY CODE */
  303. G3d_getCoordsMap(map, &regionMaxY, &regionMaxX, &regionMaxZ);
  304. /* END OF MY CODE */
  305. if ((xMin < 0) && (xMax < 0))
  306. G3d_fatalError("G3d_flushTilesInCube: coordinate out of Range");
  307. if ((xMin >= regionMaxX) && (xMax >= regionMaxX))
  308. G3d_fatalError("G3d_flushTilesInCube: coordinate out of Range");
  309. xMin = MIN(MAX(0, xMin), regionMaxX - 1);
  310. if ((yMin < 0) && (yMax < 0))
  311. G3d_fatalError("G3d_flushTilesInCube: coordinate out of Range");
  312. if ((yMin >= regionMaxY) && (yMax >= regionMaxY))
  313. G3d_fatalError("G3d_flushTilesInCube: coordinate out of Range");
  314. yMin = MIN(MAX(0, yMin), regionMaxY - 1);
  315. if ((zMin < 0) && (zMax < 0))
  316. G3d_fatalError("G3d_flushTilesInCube: coordinate out of Range");
  317. if ((zMin >= regionMaxZ) && (zMax >= regionMaxZ))
  318. G3d_fatalError("G3d_flushTilesInCube: coordinate out of Range");
  319. zMin = MIN(MAX(0, zMin), regionMaxZ - 1);
  320. G3d_coord2tileCoord(map, xMin, yMin, zMin,
  321. &xTileMin, &yTileMin, &zTileMin,
  322. &xOffs, &yOffs, &zOffs);
  323. if (xOffs != 0)
  324. xTileMin++;
  325. if (yOffs != 0)
  326. yTileMin++;
  327. if (zOffs != 0)
  328. zTileMin++;
  329. G3d_coord2tileCoord(map, xMax + 1, yMax + 1, zMax + 1,
  330. &xTileMax, &yTileMax, &zTileMax,
  331. &xOffs, &yOffs, &zOffs);
  332. xTileMax--;
  333. yTileMax--;
  334. zTileMax--;
  335. if (!G3d_flushTileCube(map, xTileMin, yTileMin, zTileMin,
  336. xTileMax, yTileMax, zTileMax)) {
  337. G3d_error("G3d_flushTilesInCube: error in G3d_flushTileCube");
  338. return 0;
  339. }
  340. return 1;
  341. }
  342. #undef MIN
  343. #undef MAX
  344. /*---------------------------------------------------------------------------*/