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 <grass/config.h>
00107 #include "G.h"
00108 #include <grass/gis.h>
00109 #include <grass/glocale.h>
00110 
00111 static int allocate_compress_buf(int);
00112 
00113 static struct fileinfo *new_fileinfo(int fd)
00114 {
00115     int oldsize = G__.fileinfo_count;
00116     int newsize = oldsize;
00117     int i;
00118 
00119     if (fd < oldsize)
00120         return &G__.fileinfo[fd];
00121 
00122     newsize *= 2;
00123     if (newsize <= fd)
00124         newsize = fd + 20;
00125 
00126     G__.fileinfo = G_realloc(G__.fileinfo, newsize * sizeof(struct fileinfo));
00127 
00128     /* Mark all cell files as closed */
00129     for (i = oldsize; i < newsize; i++)
00130         G__.fileinfo[i].open_mode = -1;
00131 
00132     G__.fileinfo_count = newsize;
00133 
00134     return &G__.fileinfo[fd];
00135 }
00136 
00176 static int G__open_raster_new(char *name, int open_mode);
00177 
00178 int G_open_cell_old (
00179     char *name,
00180     char *mapset)
00181 {
00182     int fd;
00183 
00184     if ((fd = G__open_cell_old (name, mapset)) < 0)
00185     {
00186         G_warning (_("unable to open raster map [%s in %s]"),
00187             name, mapset);
00188         return fd;
00189     }
00190 
00191 /* turn on auto masking, if not already on */
00192     G__check_for_auto_masking();
00193 /*
00194     if(G__.auto_mask <= 0)
00195          G__.mask_buf = G_allocate_cell_buf();
00196     now we don't ever free it!, so no need to allocate it  (Olga)
00197 */
00198     /* mask_buf is used for reading MASK file when mask is set and
00199        for reading map rows when the null file doesn't exist */
00200 
00201     return fd;
00202 }
00203 
00204 
00205 /********************************************************************
00206  * G__open_cell_old (name, mapset)
00207  *
00208  * function:
00209  *   This is the work horse. It is used to open cell files, supercell
00210  *   files, and the MASK file. 
00211  *
00212  * parms:
00213  *   name, mapset    name and mapset of cell file to be opened.
00214  *
00215  * actions:
00216  *   opens the named cell file, following reclass reference if
00217  *     named layer is a reclass layer.
00218  *   creates the required mapping between the data and the window
00219  *     for use by the get_map_row family of routines.
00220  *
00221  * returns:
00222  *   open file descriptor or -1 if error.
00223  *
00224  * diagnostics:
00225  *   errors other than actual open failure will cause a diagnostic to be
00226  *   delivered thru G_warning() open failure messages are left to the
00227  *   calling routine since the masking logic will want to issue a different
00228  *   warning.
00229  *
00230  * note:
00231  *  this routine does NOT open the MASK layer. If it did we would get
00232  *  infinite recursion.  This routine is called to open the mask by
00233  *  G__check_for_auto_masking() which is called by G_open_cell().
00234  ***********************************************************************/
00235 int G__open_cell_old (
00236     char *name,
00237     char *mapset)
00238 {
00239     struct fileinfo *fcb;
00240     int fd;
00241     char cell_dir[100];
00242     char *r_name ;
00243     char *r_mapset ;
00244     struct Cell_head cellhd ;
00245     int CELL_nbytes = 0;                   /* bytes per cell in CELL map */
00246     int INTERN_SIZE;
00247     int reclass_flag, i;
00248     int MAP_NBYTES;
00249     RASTER_MAP_TYPE MAP_TYPE;
00250     struct Reclass reclass;
00251 
00252 /* make sure window is set    */
00253     G__init_window ();
00254 
00255 /* Check for reclassification */
00256     reclass_flag = G_get_reclass (name, mapset, &reclass) ;
00257 
00258     switch (reclass_flag)
00259     {
00260         case 0:
00261             r_name = name ;
00262             r_mapset = mapset ;
00263             break ;
00264         case 1:
00265             r_name = reclass.name ;
00266             r_mapset = reclass.mapset ;
00267             if (G_find_cell (r_name, r_mapset) == NULL)
00268             {
00269                 G_warning (
00270                     _("unable to open [%s] in [%s] since it is a reclass of [%s] in [%s] which does not exist"),
00271                     name,mapset,r_name,r_mapset);
00272                 return -1;
00273             }
00274             break ;
00275         default:           /* Error reading cellhd/reclass file */
00276             return -1 ;
00277     }
00278 
00279 /* read the cell header */
00280     if(G_get_cellhd (r_name, r_mapset, &cellhd) < 0)
00281         return -1;
00282 
00283     /* now check the type */
00284     MAP_TYPE = G_raster_map_type (r_name, r_mapset);
00285     if (MAP_TYPE < 0) return -1;
00286 
00287     if(MAP_TYPE == CELL_TYPE)
00288     /* set the number of bytes for CELL map */
00289     {
00290        CELL_nbytes = cellhd.format + 1;
00291        if (CELL_nbytes < 1)
00292        {
00293            G_warning(_("[%s] in mapset [%s]-format field in header file invalid"),
00294                r_name, r_mapset);
00295            return -1;
00296        }
00297     }
00298 
00299     if (cellhd.proj != G__.window.proj)
00300     {
00301         G_warning (
00302             _("[%s] in mapset [%s] - in different projection than current region:\n found map [%s] in: <%s>, should be <%s> "),
00303             name, mapset, name, G__projection_name(cellhd.proj), G__projection_name(G__.window.proj));
00304         return -1;
00305     }
00306     if (cellhd.zone != G__.window.zone)
00307     {
00308         G_warning (
00309             _("[%s] in mapset [%s] - in different zone [%d] than current region [%d]"),
00310             name, mapset, cellhd.zone, G__.window.zone);
00311         return -1;
00312     }
00313 
00314 /* when map is int warn if too large cell size */
00315     if (MAP_TYPE == CELL_TYPE && CELL_nbytes > sizeof(CELL))
00316     {
00317         G_warning ( _("[%s] in [%s] - bytes per cell (%d) too large"),
00318             name, mapset, CELL_nbytes);
00319         return -1;
00320     }
00321 
00322 /* record number of bytes per cell */
00323     if(MAP_TYPE == FCELL_TYPE)
00324     {
00325       strcpy(cell_dir, "fcell");
00326       INTERN_SIZE = sizeof(FCELL);
00327       MAP_NBYTES = XDR_FLOAT_NBYTES;
00328     }
00329     else
00330       if (MAP_TYPE == DCELL_TYPE)
00331       {
00332          strcpy(cell_dir, "fcell");
00333          INTERN_SIZE = sizeof(DCELL);
00334          MAP_NBYTES = XDR_DOUBLE_NBYTES;
00335       }
00336       else /* integer */
00337       {
00338          strcpy(cell_dir, "cell");
00339          INTERN_SIZE = sizeof(CELL);
00340          MAP_NBYTES = CELL_nbytes;
00341       }
00342 
00343 /* now actually open file for reading */
00344     fd = G_open_old (cell_dir, r_name, r_mapset);
00345     if (fd < 0)
00346         return -1;
00347 
00348     fcb = new_fileinfo(fd);
00349 
00350     fcb->map_type = MAP_TYPE;
00351 
00352 /* Save cell header */
00353     G_copy ((char *) &fcb->cellhd, (char *) &cellhd, sizeof(cellhd));
00354 
00355     /* allocate null bitstream buffers for reading null rows */
00356     for (i=0;i< NULL_ROWS_INMEM; i++)
00357        fcb->NULL_ROWS[i] = G__allocate_null_bits(G__.window.cols);
00358     fcb->null_work_buf = G__allocate_null_bits(fcb->cellhd.cols);
00359     /* initialize : no NULL rows in memory */
00360     fcb->min_null_row = (-1) * NULL_ROWS_INMEM; 
00361 
00362 /* mark closed */
00363     fcb->open_mode = -1;
00364 
00365 /* save name and mapset */
00366     {
00367     char xname[512], xmapset[512];
00368     if (G__name_is_fully_qualified(name, xname, xmapset))
00369         fcb->name   = G_store (xname);
00370     else
00371         fcb->name   = G_store (name);
00372     }
00373     fcb->mapset = G_store (mapset);
00374 
00375 /* mark no data row in memory  */
00376     fcb->cur_row = -1;
00377 /* fcb->null_cur_row is not used for reading, only for writing */
00378     fcb->null_cur_row = -1;
00379 
00380 /* if reclass, copy reclass structure */
00381     if ((fcb->reclass_flag = reclass_flag))
00382         G_copy ((char *) &fcb->reclass, (char *) &reclass, sizeof(reclass));
00383 
00384 /* check for compressed data format, making initial reads if necessary */
00385     if(G__check_format (fd) < 0)
00386     {
00387         close (fd); /* warning issued by check_format() */
00388         return -1;
00389     }
00390 
00391 /* create the mapping from cell file to window */
00392     G__create_window_mapping (fd);
00393 
00394 /*
00395  * allocate the data buffer
00396  * number of bytes per cell is cellhd.format+1
00397  */
00398 
00399     /* for reading fcb->data is allocated to be fcb->cellhd.cols * fcb->nbytes 
00400       (= XDR_FLOAT/DOUBLE_NBYTES) and G__.work_buf to be G__.window.cols * 
00401       sizeof(CELL or DCELL or FCELL) */
00402     fcb->data = (unsigned char *) G_calloc (fcb->cellhd.cols, MAP_NBYTES);
00403     
00404     G__reallocate_work_buf(INTERN_SIZE);
00405     G__reallocate_mask_buf();
00406     G__reallocate_null_buf();
00407     G__reallocate_temp_buf();
00408     /* work_buf is used as intermediate buf for conversions */
00409 /*
00410  * allocate/enlarge the compressed data buffer needed by get_map_row()
00411  */
00412     allocate_compress_buf (fd);
00413 
00414 /* initialize/read in quant rules for float point maps */
00415     if(fcb->map_type != CELL_TYPE)
00416     {
00417      if (fcb->reclass_flag)
00418        G_read_quant (fcb->reclass.name, fcb->reclass.mapset, &(fcb->quant));
00419      else
00420        G_read_quant (fcb->name, fcb->mapset, &(fcb->quant));
00421     }
00422 
00423 /* now mark open for read: this must follow create_window_mapping() */
00424     fcb->open_mode = OPEN_OLD;
00425     fcb->io_error = 0;
00426     fcb->map_type = MAP_TYPE;
00427     fcb->nbytes = MAP_NBYTES;
00428     fcb->null_file_exists = -1;
00429 
00430     if(fcb->map_type != CELL_TYPE)
00431                 xdrmem_create (&fcb->xdrstream, (caddr_t) fcb->data, 
00432             (u_int) (fcb->nbytes * fcb->cellhd.cols), XDR_DECODE);
00433 
00434     return fd;
00435 }
00436 
00437 /*****************************************************************/
00438 
00439 static int WRITE_NBYTES = sizeof(CELL);
00440 /* bytes per cell for current map */
00441 
00442 static int NBYTES = sizeof(CELL);
00443 /* bytes per cell for writing integer maps */
00444 
00445 static RASTER_MAP_TYPE WRITE_MAP_TYPE = CELL_TYPE;
00446 /* a type of current map */
00447 
00448 static int COMPRESSION_TYPE = 0;
00449 
00450 #define FP_NBYTES G__.fp_nbytes
00451 /* bytes per cell for writing floating point maps */
00452 #define FP_TYPE  G__.fp_type
00453 /* a type of floating maps to be open */
00454 static int FP_TYPE_SET=0;  /* wether or not the f.p. type was set explicitly
00455                          by calling G_set_fp_type() */
00456 
00457 static char cell_dir[100];
00458 /* The mapset element for the raster map to be open: fcell, or cell */
00459 
00460 
00461 int G_open_cell_new (char *name)
00462 {
00463     WRITE_MAP_TYPE = CELL_TYPE;
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_COMPRESSED);
00468 }
00469 
00470 int G_open_cell_new_random (char *name)
00471 {
00472     WRITE_MAP_TYPE = CELL_TYPE;
00473     /* bytes per cell for current map */
00474     WRITE_NBYTES = NBYTES;
00475     strcpy(cell_dir, "cell");
00476     return G__open_raster_new (name, OPEN_NEW_RANDOM);
00477 }
00478 
00479 int G_open_cell_new_uncompressed (char *name)
00480 {
00481     WRITE_MAP_TYPE = CELL_TYPE; /* a type of current map */
00482     strcpy(cell_dir, "cell");
00483     /* bytes per cell for current map */
00484     WRITE_NBYTES = NBYTES;
00485     return G__open_raster_new (name, OPEN_NEW_UNCOMPRESSED);
00486 }
00487 
00488 int G_want_histogram (int flag)
00489 {
00490     G__.want_histogram = flag;
00491 
00492     return 0;
00493 }
00494 
00495 /* when writing float map: format is -1  */
00496 int G_set_cell_format ( int n)
00497 /* sets the format for integer raster map */
00498 {
00499     if(WRITE_MAP_TYPE == CELL_TYPE)
00500     {
00501         NBYTES = n+1;
00502         if (NBYTES <= 0)
00503             NBYTES = 1;
00504         if (NBYTES > sizeof(CELL))
00505         NBYTES = sizeof(CELL);
00506     }
00507 
00508     return 0;
00509 }
00510 
00511 int G_cellvalue_format (CELL v)
00512 {
00513     int i;
00514     if (v >= 0)
00515         for (i = 0; i < sizeof(CELL); i++)
00516             if (!(v /= 256))
00517                 return i;
00518     return sizeof(CELL)-1;
00519 }
00520 
00521 int G_open_fp_cell_new (char *name)
00522 {
00523     /* use current float. type for writing float point maps */
00524     /* if the FP type was NOT explicitly set by G_set_fp_type()
00525        use environment variable */
00526     if(!FP_TYPE_SET)
00527     {
00528        if (getenv("GRASS_FP_DOUBLE"))
00529        {
00530           FP_TYPE = DCELL_TYPE;
00531           FP_NBYTES = XDR_DOUBLE_NBYTES;
00532        }
00533        else
00534        {
00535           FP_TYPE = FCELL_TYPE;
00536           FP_NBYTES = XDR_FLOAT_NBYTES;
00537        }
00538     }
00539     WRITE_MAP_TYPE = FP_TYPE;
00540     WRITE_NBYTES = FP_NBYTES;
00541      
00542     strcpy(cell_dir, "fcell");
00543     return G__open_raster_new (name, OPEN_NEW_COMPRESSED);
00544 }       
00545 
00546 int 
00547 G_open_fp_cell_new_uncompressed (char *name)
00548 {
00549     /* use current float. type for writing float point maps */
00550     if(!FP_TYPE_SET)
00551     {
00552        if (getenv("GRASS_FP_DOUBLE"))
00553        {
00554           FP_TYPE = DCELL_TYPE;
00555           FP_NBYTES = XDR_DOUBLE_NBYTES;
00556        }
00557        else
00558        {
00559           FP_TYPE = FCELL_TYPE;
00560           FP_NBYTES = XDR_FLOAT_NBYTES;
00561        }
00562     }
00563     WRITE_MAP_TYPE = FP_TYPE;
00564     WRITE_NBYTES = FP_NBYTES;
00565      
00566     strcpy(cell_dir, "fcell");
00567     return G__open_raster_new (name, OPEN_NEW_UNCOMPRESSED);
00568 }       
00569 
00570 static int
00571 clean_check_raster_name (char *inmap, char **outmap, char **outmapset)
00572 {
00573         /* Remove mapset part of name if exists.  Also, if mapset
00574          * part exists, make sure it matches current mapset.
00575          */
00576         int status = 0;
00577         char *ptr;
00578         char *buf;
00579 
00580         buf = G_store (inmap);
00581         if ((ptr = strpbrk (buf, "@")) != NULL)
00582         {
00583                 *ptr = '\0';
00584                 ptr++;
00585                 *outmapset = G_store(G_mapset());
00586                 if ((status = strcmp(ptr, *outmapset)))
00587                 {
00588                         G_free (buf);
00589                         G_free (*outmapset);
00590                 }
00591                 else
00592                 {
00593                         *outmap = G_store (buf);
00594                         G_free (buf);
00595                 }
00596         }
00597         else
00598         {
00599                 *outmap = buf;
00600                 *outmapset = G_store(G_mapset());
00601         }
00602         return status;
00603 }
00604         
00605 /* opens a f-cell or cell file depending on WRITE_MAP_TYPE */
00606 static int G__open_raster_new (char *name, int open_mode)
00607 {
00608     struct fileinfo *fcb;
00609     int i, null_fd, fd;
00610     char *tempname;
00611     char *map;
00612     char *mapset;
00613     
00614 /* check for legal grass name */
00615     if (G_legal_filename (name) < 0)
00616     {
00617         G_warning (_("opencell: %s - illegal file name"), name);
00618         return -1;
00619     }
00620     
00621     if(clean_check_raster_name (name, &map, &mapset) != 0)
00622     {
00623             G_warning ("opencell: %s - bad mapset", name);
00624             return -1;
00625     }
00626 
00627 /* make sure window is set */
00628     G__init_window();
00629 
00630 /* open a tempfile name */
00631     tempname = G_tempfile ();
00632     fd = creat (tempname, 0666);
00633     if (fd < 0)
00634     {   
00635         G_warning ("G__open_raster_new: no temp files available");
00636         G_free (tempname);
00637         G_free (map);
00638         G_free (mapset);
00639         return -1;
00640     }
00641 
00642     fcb = new_fileinfo(fd);
00643 /*
00644  * since we are bypassing the normal open logic
00645  * must create the cell element 
00646  */
00647     G__make_mapset_element (cell_dir);
00648 
00649 /* mark closed */
00650     fcb->map_type = WRITE_MAP_TYPE;
00651     fcb->open_mode = -1;
00652 
00653     /* for writing fcb->data is allocated to be G__.window.cols * 
00654        sizeof(CELL or DCELL or FCELL) and G__.work_buf to be G__.window.cols *
00655        fcb->nbytes (= XDR_FLOAT/DOUBLE_NBYTES) */
00656     fcb->data = (unsigned char *) G_calloc (G__.window.cols, 
00657                   G_raster_size(fcb->map_type));
00658 
00659     G__reallocate_null_buf();
00660     /* we need null buffer to automatically write embeded nulls in put_row */
00661 
00662     if (open_mode == OPEN_NEW_COMPRESSED && !COMPRESSION_TYPE)
00663         COMPRESSION_TYPE = getenv("GRASS_INT_ZLIB") ? 2 : 1;
00664 
00665 /*
00666  * copy current window into cell header
00667  * set format to cell/supercell
00668  * for compressed writing
00669  *   allocate space to hold the row address array
00670  *   allocate/enlarge both the compress_buf and the work_buf
00671  */
00672     G_copy ((char *) &fcb->cellhd, (char *) &G__.window, sizeof (fcb->cellhd));
00673 
00674     if (open_mode == OPEN_NEW_COMPRESSED && fcb->map_type == CELL_TYPE)
00675     {
00676         fcb->row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t)) ;
00677         G_zero(fcb->row_ptr,(fcb->cellhd.rows + 1) * sizeof(off_t)) ;
00678         G__write_row_ptrs (fd);
00679         fcb->cellhd.compressed = COMPRESSION_TYPE;
00680 
00681         allocate_compress_buf(fd);
00682         fcb->nbytes = 1;                /* to the minimum */
00683         G__reallocate_work_buf(sizeof(CELL));
00684         G__reallocate_mask_buf();
00685         G__reallocate_temp_buf();
00686     }
00687     else
00688     {
00689         fcb->nbytes = WRITE_NBYTES ;
00690         if(open_mode == OPEN_NEW_COMPRESSED)
00691         {
00692               fcb->row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t)) ;
00693               G_zero(fcb->row_ptr,(fcb->cellhd.rows + 1) * sizeof(off_t)) ;
00694               G__write_row_ptrs (fd);
00695               fcb->cellhd.compressed = COMPRESSION_TYPE;
00696         }
00697         else
00698               fcb->cellhd.compressed = 0;
00699         G__reallocate_work_buf(fcb->nbytes);
00700         G__reallocate_mask_buf();
00701         G__reallocate_temp_buf();
00702 
00703         if(fcb->map_type != CELL_TYPE)
00704         {
00705              G_quant_init (&(fcb->quant));
00706         }
00707 
00708         if (open_mode == OPEN_NEW_RANDOM)
00709         {
00710             G_warning(_("Can't write embedded null values for map open for random access"));
00711             if(fcb->map_type == CELL_TYPE)
00712                     G_write_zeros (fd, (long) WRITE_NBYTES * fcb->cellhd.cols * fcb->cellhd.rows);
00713             else if(fcb->map_type == FCELL_TYPE)
00714             {
00715                     if (G__random_f_initialize_0 (fd, fcb->cellhd.rows, fcb->cellhd.cols)<0)
00716                           return -1;
00717             }
00718             else
00719             {
00720                     if (G__random_d_initialize_0 (fd, fcb->cellhd.rows, fcb->cellhd.cols)<0)
00721                           return -1;
00722             }
00723         }
00724     }
00725 
00726 /* save name and mapset, and tempfile name */
00727     fcb->name      = map;
00728     fcb->mapset    = mapset;
00729     fcb->temp_name = tempname;
00730 
00731 /* next row to be written (in order) is zero */
00732     fcb->cur_row = 0;
00733 
00734 /* open a null tempfile name */
00735     tempname = G_tempfile ();
00736     null_fd = creat (tempname, 0666);
00737     if (null_fd < 0)
00738     {   
00739         G_warning ("opencell opening temp null file: no temp files available");
00740         G_free (tempname);
00741         G_free (fcb->name);
00742         G_free (fcb->mapset);
00743         G_free (fcb->temp_name);
00744         close (fd);
00745         return -1;
00746     }
00747 
00748     fcb->null_temp_name = tempname;
00749     close(null_fd);
00750 
00751 /* next row to be written (in order) is zero */
00752     fcb->null_cur_row = 0;
00753 
00754     /* allocate null bitstream buffers for writing */
00755     for (i=0;i< NULL_ROWS_INMEM; i++)
00756        fcb->NULL_ROWS[i] = G__allocate_null_bits(fcb->cellhd.cols);
00757     fcb->min_null_row = (-1) * NULL_ROWS_INMEM;
00758     fcb->null_work_buf = G__allocate_null_bits(fcb->cellhd.cols);
00759 
00760 /* init cell stats */
00761 /* now works only for int maps */
00762 if(fcb->map_type == CELL_TYPE)
00763     if ((fcb->want_histogram = G__.want_histogram))
00764         G_init_cell_stats (&fcb->statf);
00765 
00766 /* init range and if map is double/float init d/f_range */
00767     G_init_range (&fcb->range);
00768 
00769     if(fcb->map_type != CELL_TYPE)
00770         G_init_fp_range (&fcb->fp_range);
00771   
00772 /* mark file as open for write */
00773     fcb->open_mode = open_mode;
00774     fcb->io_error = 0;
00775 
00776     return fd;
00777 }
00778 /*
00779  * allocate/enlarge the compressed data buffer needed by get_map_row()
00780  * and put_map_row()
00781  * note: compressed format is repeat, value:
00782  *  repeat takes 1 byte, value takes up to sizeof(CELL)
00783  *  plus 1 byte header for nbytes needed to store row
00784  */
00785 static int allocate_compress_buf(int fd)
00786 {
00787     struct fileinfo *fcb = &G__.fileinfo[fd];
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 = G__.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 = (G__.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 = (G__.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 = (G__.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    struct fileinfo *fcb = &G__.fileinfo[fd];
01072    CELL cell;
01073    DCELL dcell;
01074    struct Quant_table *p;
01075 
01076    if(fcb->open_mode!=OPEN_OLD)
01077    {
01078       G_warning("G_set_quant_rules can be called only for raster maps opened for reading");
01079       return -1;
01080    }
01081    /* copy all info from q to fcb->quant) */
01082    G_quant_init(&fcb->quant);
01083    if(q->truncate_only) 
01084    {
01085       G_quant_truncate (&fcb->quant);
01086       return 0;
01087    }
01088    for (p = &(q->table[q->nofRules - 1]); p >= q->table; p--)
01089       G_quant_add_rule(&fcb->quant, p->dLow, p->dHigh, p->cLow, p->cHigh);
01090    if(G_quant_get_neg_infinite_rule (q, &dcell, &cell)>0)
01091       G_quant_set_neg_infinite_rule (&fcb->quant, dcell, cell);
01092    if(G_quant_get_pos_infinite_rule (q, &dcell, &cell)>0)
01093       G_quant_set_pos_infinite_rule (&fcb->quant, dcell, cell);
01094 
01095    return 0;
01096 }

Generated on Wed Dec 19 14:59:06 2007 for GRASS by  doxygen 1.5.4