GRASS Programmer's Manual
6.4.2(2012)
|
00001 #include <stdio.h> 00002 #include <stdlib.h> 00003 #include <sys/types.h> 00004 #include <unistd.h> 00005 #include <rpc/types.h> 00006 #include <rpc/xdr.h> 00007 #include "G3d_intern.h" 00008 00009 00010 /*---------------------------------------------------------------------------*/ 00011 00012 static int 00013 G3d_tile2xdrTile(G3D_Map * map, const void *tile, int rows, int cols, 00014 int depths, int xRedundant, int yRedundant, int zRedundant, 00015 int nofNum, int type) 00016 { 00017 int y, z; 00018 00019 if (!G3d_initCopyToXdr(map, type)) { 00020 G3d_error("G3d_tile2xdrTile: error in G3d_initCopyToXdr"); 00021 return 0; 00022 } 00023 00024 00025 if (nofNum == map->tileSize) { 00026 if (!G3d_copyToXdr(tile, map->tileSize)) { 00027 G3d_error("G3d_tile2xdrTile: error in G3d_copyToXdr"); 00028 return 0; 00029 } 00030 return 1; 00031 } 00032 00033 if (xRedundant) { 00034 for (z = 0; z < depths; z++) { 00035 for (y = 0; y < rows; y++) { 00036 if (!G3d_copyToXdr(tile, cols)) { 00037 G3d_error("G3d_tile2xdrTile: error in G3d_copyToXdr"); 00038 return 0; 00039 } 00040 tile = G_incr_void_ptr(tile, map->tileX * G3d_length(type)); 00041 } 00042 if (yRedundant) 00043 tile = 00044 G_incr_void_ptr(tile, 00045 map->tileX * yRedundant * 00046 G3d_length(type)); 00047 } 00048 return 1; 00049 } 00050 00051 if (yRedundant) { 00052 for (z = 0; z < depths; z++) { 00053 if (!G3d_copyToXdr(tile, map->tileX * rows)) { 00054 G3d_error("G3d_tile2xdrTile: error in G3d_copyToXdr"); 00055 return 0; 00056 } 00057 tile = G_incr_void_ptr(tile, map->tileXY * G3d_length(type)); 00058 } 00059 return 1; 00060 } 00061 00062 if (!G3d_copyToXdr(tile, map->tileXY * depths)) { 00063 G3d_error("G3d_tile2xdrTile: error in G3d_copyToXdr"); 00064 return 0; 00065 } 00066 return 1; 00067 } 00068 00069 /*---------------------------------------------------------------------------*/ 00070 00071 static int G3d_writeTileUncompressed(G3D_Map * map, int nofNum) 00072 { 00073 if (write(map->data_fd, xdr, map->numLengthExtern * nofNum) != 00074 map->numLengthExtern * nofNum) { 00075 G3d_error("G3d_writeTileUncompressed: can't write file."); 00076 return 0; 00077 } 00078 00079 return 1; 00080 } 00081 00082 /*---------------------------------------------------------------------------*/ 00083 00084 static int G3d_writeTileCompressed(G3D_Map * map, int nofNum) 00085 { 00086 if (!G_fpcompress_writeXdrNums(map->data_fd, xdr, nofNum, map->precision, 00087 tmpCompress, map->type == FCELL_TYPE, 00088 map->useRle, map->useLzw)) { 00089 G3d_error 00090 ("G3d_writeTileCompressed: error in G_fpcompress_writeXdrNums"); 00091 return 0; 00092 } 00093 00094 return 1; 00095 } 00096 00097 /*---------------------------------------------------------------------------*/ 00098 00099 /*---------------------------------------------------------------------------*/ 00100 00101 /* EXPORTED FUNCTIONS */ 00102 00103 /*---------------------------------------------------------------------------*/ 00104 00105 /*---------------------------------------------------------------------------*/ 00106 00107 00128 int G3d_writeTile(G3D_Map * map, int tileIndex, const void *tile, int type) 00129 { 00130 int rows, cols, depths, xRedundant, yRedundant, zRedundant, nofNum; 00131 00132 /* valid tileIndex ? */ 00133 if ((tileIndex >= map->nTiles) || (tileIndex < 0)) 00134 G3d_fatalError("G3d_writeTile: tileIndex out of range"); 00135 00136 /* already written ? */ 00137 if (map->index[tileIndex] != -1) 00138 return 2; 00139 00140 /* save the file position */ 00141 map->index[tileIndex] = lseek(map->data_fd, (long)0, SEEK_END); 00142 if (map->index[tileIndex] == -1) { 00143 G3d_error("G3d_writeTile: can't position file"); 00144 return 0; 00145 } 00146 00147 nofNum = G3d_computeClippedTileDimensions(map, tileIndex, 00148 &rows, &cols, &depths, 00149 &xRedundant, &yRedundant, 00150 &zRedundant); 00151 00152 G3d_range_updateFromTile(map, tile, rows, cols, depths, 00153 xRedundant, yRedundant, zRedundant, nofNum, 00154 type); 00155 00156 if (!G3d_tile2xdrTile(map, tile, rows, cols, depths, 00157 xRedundant, yRedundant, zRedundant, nofNum, type)) { 00158 G3d_error("G3d_writeTileCompressed: error in G3d_tile2xdrTile"); 00159 return 0; 00160 } 00161 00162 if (map->compression == G3D_NO_COMPRESSION) { 00163 if (!G3d_writeTileUncompressed(map, nofNum)) { 00164 G3d_error("G3d_writeTile: error in G3d_writeTileUncompressed"); 00165 return 0; 00166 } 00167 } 00168 else if (!G3d_writeTileCompressed(map, nofNum)) { 00169 G3d_error("G3d_writeTile: error in G3d_writeTileCompressed"); 00170 return 0; 00171 } 00172 00173 /* compute the length */ 00174 map->tileLength[tileIndex] = lseek(map->data_fd, (long)0, SEEK_END) - 00175 map->index[tileIndex]; 00176 00177 return 1; 00178 } 00179 00180 /*---------------------------------------------------------------------------*/ 00181 00182 00194 int G3d_writeTileFloat(G3D_Map * map, int tileIndex, const void *tile) 00195 { 00196 int status; 00197 00198 if ((status = G3d_writeTile(map, tileIndex, tile, FCELL_TYPE))) 00199 return status; 00200 00201 G3d_error("G3d_writeTileFloat: error in G3d_writeTile"); 00202 return 0; 00203 } 00204 00205 /*---------------------------------------------------------------------------*/ 00206 00207 00219 int G3d_writeTileDouble(G3D_Map * map, int tileIndex, const void *tile) 00220 { 00221 int status; 00222 00223 if ((status = G3d_writeTile(map, tileIndex, tile, DCELL_TYPE))) 00224 return status; 00225 00226 G3d_error("G3d_writeTileDouble: error in G3d_writeTile"); 00227 return 0; 00228 } 00229 00230 /*---------------------------------------------------------------------------*/ 00231 00232 /* CACHE-MODE-ONLY FUNCTIONS */ 00233 00234 /*---------------------------------------------------------------------------*/ 00235 00236 00254 int G3d_flushTile(G3D_Map * map, int tileIndex) 00255 { 00256 const void *tile; 00257 00258 tile = G3d_getTilePtr(map, tileIndex); 00259 if (tile == NULL) { 00260 G3d_error("G3d_flushTile: error in G3d_getTilePtr"); 00261 return 0; 00262 } 00263 00264 if (!G3d_writeTile(map, tileIndex, tile, map->typeIntern)) { 00265 G3d_error("G3d_flushTile: error in G3d_writeTile"); 00266 return 0; 00267 } 00268 00269 if (!G3d__removeTile(map, tileIndex)) { 00270 G3d_error("G3d_flushTile: error in G3d__removeTile"); 00271 return 0; 00272 } 00273 00274 return 1; 00275 } 00276 00277 /*---------------------------------------------------------------------------*/ 00278 00279 #ifndef MIN 00280 #define MIN(a,b) (a < b ? a : b) 00281 #define MAX(a,b) (a > b ? a : b) 00282 #endif 00283 00284 00305 int 00306 G3d_flushTileCube(G3D_Map * map, int xMin, int yMin, int zMin, int xMax, 00307 int yMax, int zMax) 00308 { 00309 int x, y, z; 00310 00311 if (!map->useCache) 00312 G3d_fatalError 00313 ("G3d_flushTileCube: function invalid in non-cache mode"); 00314 00315 for (x = xMin; x <= xMax; x++) 00316 for (y = yMin; y <= yMax; y++) 00317 for (z = zMin; z <= zMax; z++) 00318 if (!G3d_flushTile(map, G3d_tile2tileIndex(map, x, y, z))) { 00319 G3d_error("G3d_flushTileCube: error in G3d_flushTile"); 00320 return 0; 00321 } 00322 00323 return 1; 00324 } 00325 00326 /*---------------------------------------------------------------------------*/ 00327 00328 00351 int 00352 G3d_flushTilesInCube(G3D_Map * map, int xMin, int yMin, int zMin, int xMax, 00353 int yMax, int zMax) 00354 { 00355 int xTileMin, yTileMin, zTileMin, xTileMax, yTileMax, zTileMax; 00356 int xOffs, yOffs, zOffs; 00357 int regionMaxX, regionMaxY, regionMaxZ; 00358 00359 if (!map->useCache) 00360 G3d_fatalError 00361 ("G3d_flushTilesInCube: function invalid in non-cache mode"); 00362 /*AV*/ 00363 /*BEGIN OF ORIGINAL CODE */ 00364 /* 00365 * G3d_getCoordsMap (map, ®ionMaxX, ®ionMaxY, ®ionMaxZ); 00366 */ 00367 /*AV*/ 00368 /* BEGIN OF MY CODE */ 00369 G3d_getCoordsMap(map, ®ionMaxY, ®ionMaxX, ®ionMaxZ); 00370 /* END OF MY CODE */ 00371 00372 if ((xMin < 0) && (xMax < 0)) 00373 G3d_fatalError("G3d_flushTilesInCube: coordinate out of Range"); 00374 if ((xMin >= regionMaxX) && (xMax >= regionMaxX)) 00375 G3d_fatalError("G3d_flushTilesInCube: coordinate out of Range"); 00376 00377 xMin = MIN(MAX(0, xMin), regionMaxX - 1); 00378 00379 if ((yMin < 0) && (yMax < 0)) 00380 G3d_fatalError("G3d_flushTilesInCube: coordinate out of Range"); 00381 if ((yMin >= regionMaxY) && (yMax >= regionMaxY)) 00382 G3d_fatalError("G3d_flushTilesInCube: coordinate out of Range"); 00383 00384 yMin = MIN(MAX(0, yMin), regionMaxY - 1); 00385 00386 if ((zMin < 0) && (zMax < 0)) 00387 G3d_fatalError("G3d_flushTilesInCube: coordinate out of Range"); 00388 if ((zMin >= regionMaxZ) && (zMax >= regionMaxZ)) 00389 G3d_fatalError("G3d_flushTilesInCube: coordinate out of Range"); 00390 00391 zMin = MIN(MAX(0, zMin), regionMaxZ - 1); 00392 00393 G3d_coord2tileCoord(map, xMin, yMin, zMin, 00394 &xTileMin, &yTileMin, &zTileMin, 00395 &xOffs, &yOffs, &zOffs); 00396 00397 if (xOffs != 0) 00398 xTileMin++; 00399 if (yOffs != 0) 00400 yTileMin++; 00401 if (zOffs != 0) 00402 zTileMin++; 00403 00404 G3d_coord2tileCoord(map, xMax + 1, yMax + 1, zMax + 1, 00405 &xTileMax, &yTileMax, &zTileMax, 00406 &xOffs, &yOffs, &zOffs); 00407 00408 xTileMax--; 00409 yTileMax--; 00410 zTileMax--; 00411 00412 if (!G3d_flushTileCube(map, xTileMin, yTileMin, zTileMin, 00413 xTileMax, yTileMax, zTileMax)) { 00414 G3d_error("G3d_flushTilesInCube: error in G3d_flushTileCube"); 00415 return 0; 00416 } 00417 00418 return 1; 00419 } 00420 00421 #undef MIN 00422 #undef MAX 00423 00424 /*---------------------------------------------------------------------------*/ 00425 00426 00440 int G3d_putDouble(); 00441 00442 00456 int G3d_putFloat(G3D_Map * map, int x, int y, int z, float value) 00457 { 00458 int tileIndex, offs; 00459 float *tile; 00460 00461 if (map->typeIntern == DCELL_TYPE) { 00462 if (!G3d_putDouble(map, x, y, z, (double)value)) { 00463 G3d_error("G3d_putFloat: error in G3d_putDouble"); 00464 return 0; 00465 } 00466 return 1; 00467 } 00468 00469 G3d_coord2tileIndex(map, x, y, z, &tileIndex, &offs); 00470 tile = (float *)G3d_getTilePtr(map, tileIndex); 00471 if (tile == NULL) { 00472 G3d_error("G3d_putFloat: error in G3d_getTilePtr"); 00473 return 0; 00474 } 00475 00476 tile[offs] = value; 00477 return 1; 00478 } 00479 00480 /*---------------------------------------------------------------------------*/ 00481 00482 00496 int G3d_putDouble(G3D_Map * map, int x, int y, int z, double value) 00497 { 00498 int tileIndex, offs; 00499 double *tile; 00500 00501 if (map->typeIntern == FCELL_TYPE) { 00502 if (!G3d_putFloat(map, x, y, z, (float)value)) { 00503 G3d_error("G3d_putDouble: error in G3d_putFloat"); 00504 return 0; 00505 } 00506 return 1; 00507 } 00508 00509 G3d_coord2tileIndex(map, x, y, z, &tileIndex, &offs); 00510 tile = (double *)G3d_getTilePtr(map, tileIndex); 00511 if (tile == NULL) { 00512 G3d_error("G3d_putDouble: error in G3d_getTilePtr"); 00513 return 0; 00514 } 00515 00516 tile[offs] = value; 00517 return 1; 00518 } 00519 00520 /*---------------------------------------------------------------------------*/ 00521 00539 int 00540 G3d_putValue(G3D_Map * map, int x, int y, int z, const void *value, int type) 00541 { 00542 if (type == FCELL_TYPE) { 00543 if (!G3d_putFloat(map, x, y, z, *((float *)value))) { 00544 G3d_error("G3d_putValue: error in G3d_putFloat"); 00545 return 0; 00546 } 00547 return 1; 00548 } 00549 00550 if (!G3d_putDouble(map, x, y, z, *((double *)value))) { 00551 G3d_error("G3d_putValue: error in G3d_putDouble"); 00552 return 0; 00553 } 00554 return 1; 00555 }