GRASS Programmer's Manual  6.4.2(2012)
tilewrite.c
Go to the documentation of this file.
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, &regionMaxX, &regionMaxY, &regionMaxZ);
00366          */
00367          /*AV*/
00368         /* BEGIN OF MY CODE */
00369         G3d_getCoordsMap(map, &regionMaxY, &regionMaxX, &regionMaxZ);
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 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines