opencell.c

Go to the documentation of this file.
00001 /**********************************************************
00002  *
00003  *  G_open_cell_old (name, mapset)
00004  *      char *name            map file name
00005  *      char *mapset          mapset containing map "name"
00006  *
00007  *  opens the existing cell file 'name' in the 'mapset'
00008  *  for reading by G_get_map_row()
00009  *  with mapping into the current window
00010  *
00011  *  returns: open file descriptor ( >= 0) if successful
00012  *           negative integer if error
00013  *
00014  *  diagnostics: warning message printed if open fails
00015  ***********************************************************
00016  *
00017  *  G_open_cell_new (name)
00018  *      char *name            map file name
00019  *
00020  *  opens a new cell file 'name' in the current mapset
00021  *  for writing by G_put_map_row()
00022  *
00023  *  the file is created and filled with no data
00024  *  it is assumed that the new cell file is to conform to
00025  *  the current window.
00026  *
00027  *  The file must be written sequentially.
00028  *   (Use G_open_cell_new_random() for non sequential writes)
00029  *
00030  *  note: the open actually creates a temporary file
00031  *        G_close_cell() will move the temporary file
00032  *        to the cell file and write out the necessary 
00033  *        support files (cellhd, cats, hist, etc.)
00034  *
00035  *  returns: open file descriptor ( >= 0) if successful
00036  *           negative integer if error
00037  *
00038  *  diagnostics: warning message printed if open fails
00039  *
00040  *  warning: calls to G_set_window() made after opening a new
00041  *           cell file may create confusion and should be avoided
00042  *           the new cell file will be created to conform
00043  *           to the window at the time of the open.
00044  ***********************************************************
00045  *
00046  *  G_open_fp_cell_new (name)
00047  *      char *name            map file name
00048  *
00049  *  opens a new floating-point map "name" in the current mapset for writing. The type
00050  *  of the file (i.e. either double or float) is determined and fixed at
00051  *  this point. The default is FCELL_TYPE. In order to change this default
00052  *  USE G_set_fp_type(type) where type is one of DCELL_TYPE or FCELL_TYPE..
00053  *  see warnings and notes for G_open_cell_new
00054  *
00055  ***********************************************************
00056  *
00057  *  G_open_raster_new(char *name, RASTER_MAP_TYPE map_type
00058  *
00059  *  opens a new raster map of type map_type
00060  *  see warnings and notes for G_open_cell_new
00061  *
00062  ***********************************************************
00063  *
00064  * RASTER_MAP_TYPE G_raster_map_type(name, mapset)
00065  * returns the type of raster map: DCELL_TYPE, FCELL_TYPE or CELL_TYPE
00066  *
00067  ***********************************************************
00068  *
00069  * 
00070  * int G_raster_map_is_fp(name, set)
00071  * returns 1 if map is float or double, 0 otherwise
00072  *
00073  ***********************************************************
00074  * G_set_cell_format(n)
00075  *
00076  * sets the format for subsequent opens on new integer cell files
00077  * (uncompressed and random only)
00078  * warning - subsequent put_row calls will only write n+1 bytes
00079  *           per cell. If the data requires more, the cell file
00080  *           will be written incorrectly (but with n+1 bytes per cell)
00081  *
00082  ***********************************************************
00083  * G_set_quant_rules(int fd, struct Quant q)
00084  *
00085  * Sets quant translation rules for raster map opened for reading.
00086  * fd is a file descriptor returned by G_open_cell_old().
00087  * After calling this function, G_get_c_raster_row() and
00088  * G_get_map_row() will use rules defined by q (instead of using
00089  * rules defined in map's quant file) to convert floats to ints.
00090  *
00091  ***********************************************************
00092  * G_want_histogram(flag)
00093  *
00094  * If newly created cell files should have histograms, set flag=1
00095  * otherwise set flag=0. Applies to subsequent opens.
00096  *
00097  ***********************************************************/
00098 
00099 #include <rpc/types.h>
00100 #include <rpc/xdr.h>
00101 #include <unistd.h>
00102 #include <string.h>
00103 #include <sys/types.h>
00104 #include <sys/stat.h>
00105 #include <fcntl.h>
00106 #include "G.h"
00107 #include "gis.h"
00108 #include "glocale.h"
00109 
00110 #define FCB G__.fileinfo[fd]
00111 #define WINDOW G__.window
00112 #define DATA_NROWS  FCB.cellhd.rows
00113 #define DATA_NCOLS  FCB.cellhd.cols
00114 static int allocate_compress_buf(int);
00115 
00155 static int G__open_raster_new(char *name, int open_mode);
00156 
00157 int G_open_cell_old (
00158     char *name,
00159     char *mapset)
00160 {
00161     int fd;
00162 
00163     if ((fd = G__open_cell_old (name, mapset)) < 0)
00164     {
00165         G_warning (_("unable to open raster map [%s in %s]"),
00166             name, mapset);
00167         return fd;
00168     }
00169 
00170 /* turn on auto masking, if not already on */
00171     G__check_for_auto_masking();
00172 /*
00173     if(G__.auto_mask <= 0)
00174          G__.mask_buf = G_allocate_cell_buf();
00175     now we don't ever free it!, so no need to allocate it  (Olga)
00176 */
00177     /* mask_buf is used for reading MASK file when mask is set and
00178        for reading map rows when the null file doesn't exist */
00179 
00180     return fd;
00181 }
00182 
00183 
00184 /********************************************************************
00185  * G__open_cell_old (name, mapset)
00186  *
00187  * function:
00188  *   This is the work horse. It is used to open cell files, supercell
00189  *   files, and the MASK file. 
00190  *
00191  * parms:
00192  *   name, mapset    name and mapset of cell file to be opened.
00193  *
00194  * actions:
00195  *   opens the named cell file, following reclass reference if
00196  *     named layer is a reclass layer.
00197  *   creates the required mapping between the data and the window
00198  *     for use by the get_map_row family of routines.
00199  *
00200  * returns:
00201  *   open file descriptor or -1 if error.
00202  *
00203  * diagnostics:
00204  *   errors other than actual open failure will cause a diagnostic to be
00205  *   delivered thru G_warning() open failure messages are left to the
00206  *   calling routine since the masking logic will want to issue a different
00207  *   warning.
00208  *
00209  * note:
00210  *  this routine does NOT open the MASK layer. If it did we would get
00211  *  infinite recursion.  This routine is called to open the mask by
00212  *  G__check_for_auto_masking() which is called by G_open_cell().
00213  ***********************************************************************/
00214 int G__open_cell_old (
00215     char *name,
00216     char *mapset)
00217 {
00218     int fd;
00219     char cell_dir[100];
00220     char *r_name ;
00221     char *r_mapset ;
00222     struct Cell_head cellhd ;
00223     int CELL_nbytes;                   /* bytes per cell in CELL map */
00224     int INTERN_SIZE;
00225     int reclass_flag, i;
00226     int MAP_NBYTES;
00227     RASTER_MAP_TYPE MAP_TYPE;
00228     struct Reclass reclass;
00229 
00230 /* make sure window is set    */
00231     G__init_window ();
00232 
00233 /* Check for reclassification */
00234     reclass_flag = G_get_reclass (name, mapset, &reclass) ;
00235 
00236     switch (reclass_flag)
00237     {
00238         case 0:
00239             r_name = name ;
00240             r_mapset = mapset ;
00241             break ;
00242         case 1:
00243             r_name = reclass.name ;
00244             r_mapset = reclass.mapset ;
00245             if (G_find_cell (r_name, r_mapset) == NULL)
00246             {
00247                 G_warning (
00248                     _("unable to open [%s] in [%s] since it is a reclass of [%s] in [%s] which does not exist"),
00249                     name,mapset,r_name,r_mapset);
00250                 return -1;
00251             }
00252             break ;
00253         default:           /* Error reading cellhd/reclass file */
00254             return -1 ;
00255     }
00256 
00257 /* read the cell header */
00258     if(G_get_cellhd (r_name, r_mapset, &cellhd) < 0)
00259         return -1;
00260 
00261     /* now check the type */
00262     MAP_TYPE = G_raster_map_type (r_name, r_mapset);
00263     if (MAP_TYPE < 0) return -1;
00264 
00265     if(MAP_TYPE == CELL_TYPE)
00266     /* set the number of bytes for CELL map */
00267     {
00268        CELL_nbytes = cellhd.format + 1;
00269        if (CELL_nbytes < 1)
00270        {
00271            G_warning(_("[%s] in mapset [%s]-format field in header file invalid"),
00272                r_name, r_mapset);
00273            return -1;
00274        }
00275     }
00276 
00277     if (cellhd.proj != G__.window.proj)
00278     {
00279         G_warning (
00280             _("[%s] in mapset [%s] - in different projection than current region:\n found map [%s] in: <%s>, should be <%s> "),
00281             name, mapset, name, G__projection_name(cellhd.proj), G__projection_name(G__.window.proj));
00282         return -1;
00283     }
00284     if (cellhd.zone != G__.window.zone)
00285     {
00286         G_warning (
00287             _("[%s] in mapset [%s] - in different zone [%d] than current region [%d]"),
00288             name, mapset, cellhd.zone, G__.window.zone);
00289         return -1;
00290     }
00291 
00292 /* when map is int warn if too large cell size */
00293     if (MAP_TYPE == CELL_TYPE && CELL_nbytes > sizeof(CELL))
00294     {
00295         G_warning ( _("[%s] in [%s] - bytes per cell (%d) too large"),
00296             name, mapset, CELL_nbytes);
00297         return -1;
00298     }
00299 
00300 /* record number of bytes per cell */
00301     if(MAP_TYPE == FCELL_TYPE)
00302     {
00303       strcpy(cell_dir, "fcell");
00304       INTERN_SIZE = sizeof(FCELL);
00305       MAP_NBYTES = XDR_FLOAT_NBYTES;
00306     }
00307     else
00308       if (MAP_TYPE == DCELL_TYPE)
00309       {
00310          strcpy(cell_dir, "fcell");
00311          INTERN_SIZE = sizeof(DCELL);
00312          MAP_NBYTES = XDR_DOUBLE_NBYTES;
00313       }
00314       else /* integer */
00315       {
00316          strcpy(cell_dir, "cell");
00317          INTERN_SIZE = sizeof(CELL);
00318          MAP_NBYTES = CELL_nbytes;
00319       }
00320 
00321 /* now actually open file for reading */
00322     fd = G_open_old (cell_dir, r_name, r_mapset);
00323     if (fd < 0)
00324         return -1;
00325 
00326     if (fd >= MAXFILES)
00327     {
00328         close (fd);
00329         G_warning("Too many open raster files");
00330         return -1;
00331     }
00332     FCB.map_type = MAP_TYPE;
00333 
00334 /* Save cell header */
00335     G_copy ((char *) &FCB.cellhd, (char *) &cellhd, sizeof(cellhd));
00336 
00337     /* allocate null bitstream buffers for reading null rows */
00338     for (i=0;i< NULL_ROWS_INMEM; i++)
00339        FCB.NULL_ROWS[i] = G__allocate_null_bits(WINDOW.cols);
00340     FCB.null_work_buf = G__allocate_null_bits(FCB.cellhd.cols);
00341     /* initialize : no NULL rows in memory */
00342     FCB.min_null_row = (-1) * NULL_ROWS_INMEM; 
00343 
00344 /* mark closed */
00345     FCB.open_mode = -1;
00346 
00347 /* save name and mapset */
00348     {
00349     char xname[512], xmapset[512];
00350     if (G__name_is_fully_qualified(name, xname, xmapset))
00351         FCB.name   = G_store (xname);
00352     else
00353         FCB.name   = G_store (name);
00354     }
00355     FCB.mapset = G_store (mapset);
00356 
00357 /* mark no data row in memory  */
00358     FCB.cur_row = -1;
00359 /* FCB.null_cur_row is not used for reading, only for writing */
00360     FCB.null_cur_row = -1;
00361 
00362 /* if reclass, copy reclass structure */
00363     if ((FCB.reclass_flag = reclass_flag))
00364         G_copy ((char *) &FCB.reclass, (char *) &reclass, sizeof(reclass));
00365 
00366 /* check for compressed data format, making initial reads if necessary */
00367     if(G__check_format (fd) < 0)
00368     {
00369         close (fd); /* warning issued by check_format() */
00370         return -1;
00371     }
00372 
00373 /* create the mapping from cell file to window */
00374     G__create_window_mapping (fd);
00375 
00376 /*
00377  * allocate the data buffer
00378  * number of bytes per cell is cellhd.format+1
00379  */
00380 
00381     /* for reading FCB.data is allocated to be FCB.cellhd.cols * FCB.nbytes 
00382       (= XDR_FLOAT/DOUBLE_NBYTES) and G__.work_buf to be WINDOW.cols * 
00383       sizeof(CELL or DCELL or FCELL) */
00384     FCB.data = (unsigned char *) G_calloc (FCB.cellhd.cols, MAP_NBYTES);
00385     
00386     G__reallocate_work_buf(INTERN_SIZE);
00387     G__reallocate_mask_buf();
00388     G__reallocate_null_buf();
00389     G__reallocate_temp_buf();
00390     /* work_buf is used as intermediate buf for conversions */
00391 /*
00392  * allocate/enlarge the compressed data buffer needed by get_map_row()
00393  */
00394     allocate_compress_buf (fd);
00395 
00396 /* initialize/read in quant rules for float point maps */
00397     if(FCB.map_type != CELL_TYPE)
00398     {
00399      if (FCB.reclass_flag)
00400        G_read_quant (FCB.reclass.name, FCB.reclass.mapset, &(FCB.quant));
00401      else
00402        G_read_quant (FCB.name, FCB.mapset, &(FCB.quant));
00403     }
00404 
00405 /* now mark open for read: this must follow create_window_mapping() */
00406     FCB.open_mode = OPEN_OLD;
00407     FCB.io_error = 0;
00408     FCB.map_type = MAP_TYPE;
00409     FCB.nbytes = MAP_NBYTES;
00410     FCB.null_file_exists = -1;
00411 
00412     if(FCB.map_type != CELL_TYPE)
00413                 xdrmem_create (&FCB.xdrstream, (caddr_t) FCB.data, 
00414             (u_int) (FCB.nbytes * FCB.cellhd.cols), XDR_DECODE);
00415 
00416     return fd;
00417 }
00418 
00419 /*****************************************************************/
00420 
00421 static int WRITE_NBYTES = sizeof(CELL);
00422 /* bytes per cell for current map */
00423 
00424 static int NBYTES = sizeof(CELL);
00425 /* bytes per cell for writing integer maps */
00426 
00427 static RASTER_MAP_TYPE WRITE_MAP_TYPE = CELL_TYPE;
00428 /* a type of current map */
00429 
00430 static int COMPRESSION_TYPE = 0;
00431 
00432 #define FP_NBYTES G__.fp_nbytes
00433 /* bytes per cell for writing floating point maps */
00434 #define FP_TYPE  G__.fp_type
00435 /* a type of floating maps to be open */
00436 static int FP_TYPE_SET=0;  /* wether or not the f.p. type was set explicitly
00437                          by calling G_set_fp_type() */
00438 
00439 static char cell_dir[100];
00440 /* The mapset element for the raster map to be open: fcell, or cell */
00441 
00442 
00443 int G_open_cell_new (char *name)
00444 {
00445     WRITE_MAP_TYPE = CELL_TYPE;
00446     strcpy(cell_dir, "cell");
00447     /* bytes per cell for current map */
00448     WRITE_NBYTES = NBYTES;
00449     return G__open_raster_new (name, OPEN_NEW_COMPRESSED);
00450 }
00451 
00452 int G_open_cell_new_random (char *name)
00453 {
00454     WRITE_MAP_TYPE = CELL_TYPE;
00455     /* bytes per cell for current map */
00456     WRITE_NBYTES = NBYTES;
00457     strcpy(cell_dir, "cell");
00458     return G__open_raster_new (name, OPEN_NEW_RANDOM);
00459 }
00460 
00461 int G_open_cell_new_uncompressed (char *name)
00462 {
00463     WRITE_MAP_TYPE = CELL_TYPE; /* a type of current map */
00464     strcpy(cell_dir, "cell");
00465     /* bytes per cell for current map */
00466     WRITE_NBYTES = NBYTES;
00467     return G__open_raster_new (name, OPEN_NEW_UNCOMPRESSED);
00468 }
00469 
00470 int G_want_histogram (int flag)
00471 {
00472     G__.want_histogram = flag;
00473 
00474     return 0;
00475 }
00476 
00477 /* when writing float map: format is -1  */
00478 int G_set_cell_format ( int n)
00479 /* sets the format for integer raster map */
00480 {
00481     if(WRITE_MAP_TYPE == CELL_TYPE)
00482     {
00483         NBYTES = n+1;
00484         if (NBYTES <= 0)
00485             NBYTES = 1;
00486         if (NBYTES > sizeof(CELL))
00487         NBYTES = sizeof(CELL);
00488     }
00489 
00490     return 0;
00491 }
00492 
00493 int G_cellvalue_format (CELL v)
00494 {
00495     int i;
00496     if (v >= 0)
00497         for (i = 0; i < sizeof(CELL); i++)
00498             if (!(v /= 256))
00499                 return i;
00500     return sizeof(CELL)-1;
00501 }
00502 
00503 int G_open_fp_cell_new (char *name)
00504 {
00505     /* use current float. type for writing float point maps */
00506     /* if the FP type was NOT explicitly set by G_set_fp_type()
00507        use environment variable */
00508     if(!FP_TYPE_SET)
00509     {
00510        if (getenv("GRASS_FP_DOUBLE"))
00511        {
00512           FP_TYPE = DCELL_TYPE;
00513           FP_NBYTES = XDR_DOUBLE_NBYTES;
00514        }
00515        else
00516        {
00517           FP_TYPE = FCELL_TYPE;
00518           FP_NBYTES = XDR_FLOAT_NBYTES;
00519        }
00520     }
00521     WRITE_MAP_TYPE = FP_TYPE;
00522     WRITE_NBYTES = FP_NBYTES;
00523      
00524     strcpy(cell_dir, "fcell");
00525     return G__open_raster_new (name, OPEN_NEW_COMPRESSED);
00526 }       
00527 
00528 int 
00529 G_open_fp_cell_new_uncompressed (char *name)
00530 {
00531     /* use current float. type for writing float point maps */
00532     if(!FP_TYPE_SET)
00533     {
00534        if (getenv("GRASS_FP_DOUBLE"))
00535        {
00536           FP_TYPE = DCELL_TYPE;
00537           FP_NBYTES = XDR_DOUBLE_NBYTES;
00538        }
00539        else
00540        {
00541           FP_TYPE = FCELL_TYPE;
00542           FP_NBYTES = XDR_FLOAT_NBYTES;
00543        }
00544     }
00545     WRITE_MAP_TYPE = FP_TYPE;
00546     WRITE_NBYTES = FP_NBYTES;
00547      
00548     strcpy(cell_dir, "fcell");
00549     return G__open_raster_new (name, OPEN_NEW_UNCOMPRESSED);
00550 }       
00551 
00552 static int
00553 clean_check_raster_name (char *inmap, char **outmap, char **outmapset)
00554 {
00555         /* Remove mapset part of name if exists.  Also, if mapset
00556          * part exists, make sure it matches current mapset.
00557          */
00558         int status = 0;
00559         char *ptr;
00560         char *buf;
00561 
00562         buf = G_store (inmap);
00563         if ((ptr = strpbrk (buf, "@")) != NULL)
00564         {
00565                 *ptr = '\0';
00566                 ptr++;
00567                 *outmapset = G_store(G_mapset());
00568                 if ((status = strcmp(ptr, *outmapset)))
00569                 {
00570                         G_free (buf);
00571                         G_free (*outmapset);
00572                 }
00573                 else
00574                 {
00575                         *outmap = G_store (buf);
00576                         G_free (buf);
00577                 }
00578         }
00579         else
00580         {
00581                 *outmap = buf;
00582                 *outmapset = G_store(G_mapset());
00583         }
00584         return status;
00585 }
00586         
00587 /* opens a f-cell or cell file depending on WRITE_MAP_TYPE */
00588 static int G__open_raster_new (char *name, int open_mode)
00589 {
00590     int i, null_fd, fd;
00591     char *tempname;
00592     char *map;
00593     char *mapset;
00594     
00595 /* check for legal grass name */
00596     if (G_legal_filename (name) < 0)
00597     {
00598         G_warning (_("opencell: %s - illegal file name"), name);
00599         return -1;
00600     }
00601     
00602     if(clean_check_raster_name (name, &map, &mapset) != 0)
00603     {
00604             G_warning ("opencell: %s - bad mapset", name);
00605             return -1;
00606     }
00607 
00608 /* make sure window is set */
00609     G__init_window();
00610 
00611 /* open a tempfile name */
00612     tempname = G_tempfile ();
00613     fd = creat (tempname, 0666);
00614     if (fd < 0)
00615     {   
00616         G_warning ("G__open_raster_new: no temp files available");
00617         G_free (tempname);
00618         G_free (map);
00619         G_free (mapset);
00620         return -1;
00621     }
00622 
00623     if (fd >= MAXFILES)
00624     {
00625         G_free (tempname);
00626         G_free (map);
00627         G_free (mapset);
00628         close (fd);
00629         G_warning("G__open_raster_new: too many open files");
00630         return -1;
00631     }
00632 
00633 /*
00634  * since we are bypassing the normal open logic
00635  * must create the cell element 
00636  */
00637     G__make_mapset_element (cell_dir);
00638 
00639 /* mark closed */
00640     FCB.map_type = WRITE_MAP_TYPE;
00641     FCB.open_mode = -1;
00642 
00643     /* for writing FCB.data is allocated to be WINDOW.cols * 
00644        sizeof(CELL or DCELL or FCELL) and G__.work_buf to be WINDOW.cols *
00645        FCB.nbytes (= XDR_FLOAT/DOUBLE_NBYTES) */
00646     FCB.data = (unsigned char *) G_calloc (WINDOW.cols, 
00647                   G_raster_size(FCB.map_type));
00648 
00649     G__reallocate_null_buf();
00650     /* we need null buffer to automatically write embeded nulls in put_row */
00651 
00652     if (open_mode == OPEN_NEW_COMPRESSED && !COMPRESSION_TYPE)
00653         COMPRESSION_TYPE = getenv("GRASS_INT_ZLIB") ? 2 : 1;
00654 
00655 /*
00656  * copy current window into cell header
00657  * set format to cell/supercell
00658  * for compressed writing
00659  *   allocate space to hold the row address array
00660  *   allocate/enlarge both the compress_buf and the work_buf
00661  */
00662     G_copy ((char *) &FCB.cellhd, (char *) &WINDOW, sizeof (FCB.cellhd));
00663     if (open_mode == OPEN_NEW_COMPRESSED && FCB.map_type == CELL_TYPE)
00664     {
00665         FCB.row_ptr = G_calloc(DATA_NROWS + 1, sizeof(off_t)) ;
00666         G_zero(FCB.row_ptr,(DATA_NROWS + 1) * sizeof(off_t)) ;
00667         G__write_row_ptrs (fd);
00668         FCB.cellhd.compressed = COMPRESSION_TYPE;
00669 
00670         allocate_compress_buf(fd);
00671         FCB.nbytes = 1;         /* to the minimum */
00672         G__reallocate_work_buf(sizeof(CELL));
00673         G__reallocate_mask_buf();
00674         G__reallocate_temp_buf();
00675     }
00676     else
00677     {
00678         FCB.nbytes = WRITE_NBYTES ;
00679         if(open_mode == OPEN_NEW_COMPRESSED)
00680         {
00681               FCB.row_ptr = G_calloc(DATA_NROWS + 1, sizeof(off_t)) ;
00682               G_zero(FCB.row_ptr,(DATA_NROWS + 1) * sizeof(off_t)) ;
00683               G__write_row_ptrs (fd);
00684               FCB.cellhd.compressed = COMPRESSION_TYPE;
00685         }
00686         else
00687               FCB.cellhd.compressed = 0;
00688         G__reallocate_work_buf(FCB.nbytes);
00689         G__reallocate_mask_buf();
00690         G__reallocate_temp_buf();
00691 
00692         if(FCB.map_type != CELL_TYPE)
00693         {
00694              G_quant_init (&(FCB.quant));
00695         }
00696 
00697         if (open_mode == OPEN_NEW_RANDOM)
00698         {
00699             G_warning(_("Can't write embedded null values for map open for random access"));
00700             if(FCB.map_type == CELL_TYPE)
00701                     G_write_zeros (fd, (long) WRITE_NBYTES * DATA_NCOLS * DATA_NROWS);
00702             else if(FCB.map_type == FCELL_TYPE)
00703             {
00704                     if (G__random_f_initialize_0 (fd, DATA_NROWS, DATA_NCOLS)<0)
00705                           return -1;
00706             }
00707             else
00708             {
00709                     if (G__random_d_initialize_0 (fd, DATA_NROWS, DATA_NCOLS)<0)
00710                           return -1;
00711             }
00712         }
00713     }
00714 
00715 /* save name and mapset, and tempfile name */
00716     FCB.name      = map;
00717     FCB.mapset    = mapset;
00718     FCB.temp_name = tempname;
00719 
00720 /* next row to be written (in order) is zero */
00721     FCB.cur_row = 0;
00722 
00723 /* open a null tempfile name */
00724     tempname = G_tempfile ();
00725     null_fd = creat (tempname, 0666);
00726     if (null_fd < 0)
00727     {   
00728         G_warning ("opencell opening temp null file: no temp files available");
00729         G_free (tempname);
00730         G_free (FCB.name);
00731         G_free (FCB.mapset);
00732         G_free (FCB.temp_name);
00733         close (fd);
00734         return -1;
00735     }
00736 
00737     if (null_fd >= MAXFILES)
00738     {
00739         G_free (tempname);
00740         close (null_fd);
00741         G_free (FCB.name);
00742         G_free (FCB.mapset);
00743         G_free (FCB.temp_name);
00744         close (fd);
00745         G_warning("opencell: too many open files");
00746         return -1;
00747     }
00748 
00749     FCB.null_temp_name = tempname;
00750     close(null_fd);
00751 
00752 /* next row to be written (in order) is zero */
00753     FCB.null_cur_row = 0;
00754 
00755     /* allocate null bitstream buffers for writing */
00756     for (i=0;i< NULL_ROWS_INMEM; i++)
00757        FCB.NULL_ROWS[i] = G__allocate_null_bits(FCB.cellhd.cols);
00758     FCB.min_null_row = (-1) * NULL_ROWS_INMEM;
00759     FCB.null_work_buf = G__allocate_null_bits(FCB.cellhd.cols);
00760 
00761 /* init cell stats */
00762 /* now works only for int maps */
00763 if(FCB.map_type == CELL_TYPE)
00764     if ((FCB.want_histogram = G__.want_histogram))
00765         G_init_cell_stats (&FCB.statf);
00766 
00767 /* init range and if map is double/float init d/f_range */
00768     G_init_range (&FCB.range);
00769 
00770     if(FCB.map_type != CELL_TYPE)
00771         G_init_fp_range (&FCB.fp_range);
00772   
00773 /* mark file as open for write */
00774     FCB.open_mode = open_mode;
00775     FCB.io_error = 0;
00776 
00777     return fd;
00778 }
00779 /*
00780  * allocate/enlarge the compressed data buffer needed by get_map_row()
00781  * and put_map_row()
00782  * note: compressed format is repeat, value:
00783  *  repeat takes 1 byte, value takes up to sizeof(CELL)
00784  *  plus 1 byte header for nbytes needed to store row
00785  */
00786 static int allocate_compress_buf(int fd)
00787 {
00788     int n;
00789     n = FCB.cellhd.cols * (sizeof(CELL) + 1) + 1;
00790     if (FCB.cellhd.compressed && FCB.map_type == CELL_TYPE && (n > G__.compressed_buf_size))
00791     {
00792         if (G__.compressed_buf_size <= 0)
00793             G__.compressed_buf = (unsigned char *) G_malloc (n);
00794         else
00795             G__.compressed_buf = (unsigned char *) G_realloc((char *) G__.compressed_buf,n);
00796         G__.compressed_buf_size  = n;
00797     }
00798 
00799     return 0;
00800 }
00801 /*
00802  * allocate/enlarge the work data buffer needed by get_map_row and put_map_row()
00803  */
00804 int G__reallocate_work_buf (int bytes_per_cell)
00805 {
00806     int n;
00807     n = WINDOW.cols * (bytes_per_cell + 1) + 1;
00808     if (n > G__.work_buf_size)
00809     {
00810         if (G__.work_buf_size <= 0)
00811             G__.work_buf = (unsigned char *) G_malloc (n);
00812         else
00813             G__.work_buf = (unsigned char *) G_realloc((char *) G__.work_buf,n);
00814         G__.work_buf_size  = n;
00815     }
00816 
00817     return 0;
00818 }
00819 
00820 /*
00821  * allocate/enlarge the null data buffer needed by get_map_row()
00822  * and for conversion in put_row 
00823  */
00824 int G__reallocate_null_buf (void)
00825 {
00826     int n;
00827     n = (WINDOW.cols + 1) * sizeof(char);
00828     if (n > G__.null_buf_size)
00829     {
00830         if (G__.null_buf_size <= 0)
00831             G__.null_buf = (char *) G_malloc (n);
00832         else
00833             G__.null_buf = (char *) G_realloc(G__.null_buf,n);
00834         G__.null_buf_size  = n;
00835     }
00836 
00837     return 0;
00838 }
00839 
00840 /*
00841  * allocate/enlarge the mask buffer needed by get_map_row()
00842  */
00843 int G__reallocate_mask_buf (void)
00844 {
00845     int n;
00846     n = (WINDOW.cols + 1) * sizeof(CELL);
00847     if (n > G__.mask_buf_size)
00848     {
00849         if (G__.mask_buf_size <= 0)
00850             G__.mask_buf = (CELL *) G_malloc (n);
00851         else
00852             G__.mask_buf = (CELL *) G_realloc((char *) G__.mask_buf,n);
00853         G__.mask_buf_size  = n;
00854     }
00855 
00856     return 0;
00857 }
00858 
00859 /*
00860  * allocate/enlarge the temporary buffer needed by G_get_raster_row[_nomask]
00861  */
00862 int G__reallocate_temp_buf (void)
00863 {
00864     int n;
00865     n = (WINDOW.cols + 1) * sizeof(CELL);
00866     if (n > G__.temp_buf_size)
00867     {
00868         if (G__.temp_buf_size <= 0)
00869             G__.temp_buf = (CELL *) G_malloc (n);
00870         else
00871             G__.temp_buf = (CELL *) G_realloc((char *) G__.temp_buf,n);
00872         G__.temp_buf_size  = n;
00873     }
00874 
00875     return 0;
00876 }
00877 
00878 
00891  int G_set_fp_type (RASTER_MAP_TYPE map_type)
00892 {
00893     FP_TYPE_SET = 1;
00894     if (map_type!=FCELL_TYPE && map_type != DCELL_TYPE) 
00895     {
00896         G_warning("G_set_fp_type() can only be called with FCELL_TYPE or DCELL_TYPE");
00897         return -1;
00898     }
00899     FP_TYPE = map_type;
00900     if(map_type == DCELL_TYPE)
00901          FP_NBYTES = XDR_DOUBLE_NBYTES;
00902     else
00903          FP_NBYTES = XDR_FLOAT_NBYTES;
00904 
00905     return 1;
00906 }
00907 
00908 
00909 #define FORMAT_FILE "f_format"
00910 
00911 
00924  int G_raster_map_is_fp (char *name, char *mapset)
00925 {
00926    char path[1024];
00927 
00928    if (G_find_cell (name, mapset) == NULL)
00929    {
00930       G_warning (_("unable to find [%s] in [%s]"),name,mapset);
00931       return -1;
00932    }
00933    G__file_name(path,"fcell", name, mapset);
00934    if (access(path,0) == 0) return 1;
00935    G__file_name(path, "g3dcell", name, mapset);
00936    if (access(path,0) == 0) return 1;
00937    return 0;
00938 }
00939 
00940 RASTER_MAP_TYPE G_raster_map_type (char *name, char *mapset)
00941 
00942 /* Determines if the raster map is floating point or integer. Returns
00943 DCELL_TYPE for double maps, FCELL_TYPE for float maps, CELL_TYPE for 
00944 integer maps, -1 if error has occured */
00945 
00946 {
00947    char path[1024];
00948 
00949    if (G_find_cell (name, mapset) == NULL)
00950    {
00951       G_warning (_("unable to find [%s] in [%s]"),name,mapset);
00952       return -1;
00953    }
00954    G__file_name(path,"fcell", name, mapset);
00955    if (access(path,0) == 0) return G__check_fp_type(name,mapset);
00956    G__file_name(path, "g3dcell", name, mapset);
00957    if (access(path,0) == 0) return DCELL_TYPE;
00958    return CELL_TYPE;
00959 }
00960 
00961 
00962 RASTER_MAP_TYPE G__check_fp_type (char *name, char *mapset)
00963 /* determines whether the flotsing points cell file has double or float type */
00964 /* returns DCELL_TYPE for double, FCELL_TYPE for float, -1 for error */
00965 /* f_format file:
00966    type: float/double
00967    byte_order: xdr/bytes? 
00968 */
00969 
00970 {
00971    char path[1024];
00972    char element[100];
00973    struct Key_Value *format_keys;
00974    int in_stat;
00975    char *str,*str1;
00976    RASTER_MAP_TYPE map_type;
00977 
00978    sprintf(element,"cell_misc/%s",name); 
00979    G__file_name(path,element,FORMAT_FILE,mapset);
00980      
00981    if (access(path,0) != 0) {
00982       G_warning (_("unable to find [%s]"),path);
00983       return -1;
00984    }
00985    format_keys = G_read_key_value_file(path, &in_stat);
00986    if (in_stat !=0)
00987    {
00988       G_warning ( _("Unable to open %s"),path);
00989       return -1;
00990    }
00991    if ((str = G_find_key_value("type",format_keys))!=NULL) {
00992      G_strip(str);
00993      if (strcmp(str,"double") == 0) map_type = DCELL_TYPE;
00994      else 
00995        if (strcmp(str,"float") == 0) map_type = FCELL_TYPE;
00996        else {
00997          G_warning(_("invalid type: field %s in file %s "),str,path);
00998          G_free_key_value(format_keys);
00999          return -1;
01000        }
01001    }
01002    else 
01003    {
01004        G_free_key_value(format_keys);
01005        return -1;
01006    }
01007 
01008    if ((str1 = G_find_key_value("byte_order",format_keys))!=NULL) 
01009    {
01010      G_strip(str1);
01011      if (strcmp(str1,"xdr") != 0)  
01012          G_warning ("the map %s is not xdr: byte_order: %s",name, str);
01013          /* here read and translate  byte order if not using xdr */
01014    }
01015    G_free_key_value(format_keys);
01016    return map_type;
01017 } 
01018 
01019 int G_open_raster_new (char *name, RASTER_MAP_TYPE wr_type)
01020 {
01021     int fd;
01022 
01023     if (G_legal_filename (name) < 0)
01024         G_fatal_error ("%s - ** illegal name **", name);
01025 
01026     if(wr_type == CELL_TYPE)
01027        return G_open_cell_new (name);
01028     else
01029     {
01030         G_set_fp_type(wr_type);
01031         fd = G_open_fp_cell_new (name);
01032     }
01033 
01034     return fd;
01035 }
01036 
01037 int G_open_raster_new_uncompressed (char *name, RASTER_MAP_TYPE wr_type)
01038 {
01039     int fd;
01040 
01041     if (G_legal_filename (name) < 0)
01042         G_fatal_error (_("%s - ** illegal name **"), name);
01043 
01044     if(wr_type == CELL_TYPE)
01045        return G_open_cell_new_uncompressed (name);
01046 
01047     G_set_fp_type(wr_type);
01048     fd = G_open_fp_cell_new_uncompressed (name);
01049 
01050     return fd;
01051 }
01052 
01053 
01069  int G_set_quant_rules (int fd, struct Quant *q)
01070 {
01071    CELL cell;
01072    DCELL dcell;
01073    struct Quant_table *p;
01074 
01075    if(FCB.open_mode!=OPEN_OLD)
01076    {
01077       G_warning("G_set_quant_rules can be called only for raster maps opened for reading");
01078       return -1;
01079    }
01080    /* copy all info from q to FCB.quant) */
01081    G_quant_init(&FCB.quant);
01082    if(q->truncate_only) 
01083    {
01084       G_quant_truncate (&FCB.quant);
01085       return 0;
01086    }
01087    for (p = &(q->table[q->nofRules - 1]); p >= q->table; p--)
01088       G_quant_add_rule(&FCB.quant, p->dLow, p->dHigh, p->cLow, p->cHigh);
01089    if(G_quant_get_neg_infinite_rule (q, &dcell, &cell)>0)
01090       G_quant_set_neg_infinite_rule (&FCB.quant, dcell, cell);
01091    if(G_quant_get_pos_infinite_rule (q, &dcell, &cell)>0)
01092       G_quant_set_pos_infinite_rule (&FCB.quant, dcell, cell);
01093 
01094    return 0;
01095 }

Generated on Mon Jan 1 19:49:25 2007 for GRASS by  doxygen 1.5.1