closecell.c

Go to the documentation of this file.
00001 /***********************************************************************
00002  *
00003  *   G_close_cell(fd)
00004  *      Closes and does housekeeping on an opened cell file
00005  *
00006  *   G_unopen_cell(fd)
00007  *      Closes and does housekeeping on an opened cell file
00008  *      without creating the cell file
00009  *
00010  *   parms:
00011  *      int fd     open cell file
00012  *
00013  *   returns:
00014  *      -1   on fail
00015  *       0   on success
00016  *
00017  *   note:
00018  *      On closing of a cell file that was open for writing, dummy cats
00019  *      and history files are created. Histogram and range info are written.
00020  *
00021  **********************************************************************/
00022 
00023 #ifdef __MINGW32__
00024 #  include <windows.h>
00025 #endif
00026 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <unistd.h>
00031 #include <fcntl.h>
00032 #include <signal.h>
00033 #include <grass/gis.h>
00034 #include <grass/glocale.h>
00035 #include "G.h"
00036 
00037 #define FORMAT_FILE "f_format"
00038 #define NULL_FILE   "null"
00039 
00040 static int close_old (int);
00041 static int close_new (int,int);
00042 static char CELL_DIR[100];
00043 
00044 
00077 int G_close_cell (int fd)
00078 {
00079     struct fileinfo *fcb = &G__.fileinfo[fd];
00080 
00081     if (fd < 0 || fd >= G__.fileinfo_count || fcb->open_mode <= 0)
00082         return -1;
00083     if (fcb->open_mode == OPEN_OLD)
00084         return close_old (fd);
00085 
00086     return close_new (fd, 1);
00087 }
00088 
00089 
00110 int G_unopen_cell (int fd)
00111 {
00112     struct fileinfo *fcb = &G__.fileinfo[fd];
00113 
00114     if (fd < 0 || fd >= G__.fileinfo_count || fcb->open_mode <= 0)
00115         return -1;
00116     if (fcb->open_mode == OPEN_OLD)
00117         return close_old (fd);
00118     else
00119         return close_new (fd, 0);
00120 }
00121 
00122 static int close_old (int fd)
00123 {
00124     struct fileinfo *fcb = &G__.fileinfo[fd];
00125     int i;
00126 
00127     /* if G__.auto_mask was only allocated for reading map rows to create
00128        non-existant null rows, and not for actuall mask, free G__.mask_row 
00129        if(G__.auto_mask <=0)
00130           G_free (G__.mask_buf);
00131        This is obsolete since now the mask_bus is always allocated
00132     */
00133 
00134     for (i=0;i<NULL_ROWS_INMEM;i++)
00135        G_free (fcb->NULL_ROWS[i]);
00136     G_free (fcb->null_work_buf);
00137 
00138     if (fcb->cellhd.compressed)
00139         G_free (fcb->row_ptr);
00140     G_free (fcb->col_map);
00141     G_free (fcb->mapset);
00142     G_free (fcb->data);
00143     G_free (fcb->name);
00144     if (fcb->reclass_flag)
00145         G_free_reclass (&fcb->reclass);
00146     fcb->open_mode = -1;
00147 
00148     if(fcb->map_type != CELL_TYPE)
00149     {
00150         G_quant_free(&fcb->quant);
00151         xdr_destroy(&fcb->xdrstream);
00152     } 
00153     close (fd);
00154 
00155     return 1;
00156 }
00157 
00158 static int close_new (int fd,int ok)
00159 {
00160     struct fileinfo *fcb = &G__.fileinfo[fd];
00161     int stat;
00162     struct Categories cats;
00163     struct History hist;
00164     char path[4096];
00165     CELL cell_min, cell_max;
00166     int row, i, open_mode;
00167     char element[100];
00168 
00169     if (ok) {
00170         switch (fcb->open_mode)
00171         {
00172         case OPEN_NEW_COMPRESSED:
00173             G_debug(1, "close %s compressed", fcb->name); 
00174             break;
00175         case OPEN_NEW_UNCOMPRESSED:
00176             G_debug(1, "close %s uncompressed", fcb->name);
00177             break;
00178         case OPEN_NEW_RANDOM:
00179             G_debug(1, "close %s random", fcb->name);
00180             break;
00181         }
00182 
00183         if (fcb->open_mode != OPEN_NEW_RANDOM && fcb->cur_row < fcb->cellhd.rows) {
00184             G_zero_raster_buf (fcb->data, fcb->map_type);
00185             for (row = fcb->cur_row; row < fcb->cellhd.rows; row++)
00186                 G_put_raster_row (fd, fcb->data, fcb->map_type);
00187             G_free (fcb->data);
00188             fcb->data = NULL;
00189         }
00190 
00191         /* create path : full null file name */
00192         sprintf(element,"cell_misc/%s",fcb->name);
00193         G__file_name(path, element, NULL_FILE, G_mapset());
00194         G__make_mapset_element(element);
00195         remove ( path );
00196 
00197         if(fcb->null_cur_row > 0) {
00198         /* if temporary NULL file exists, write it into cell_misc/name/null */
00199             int null_fd;
00200 
00201             null_fd = G__open_null_write(fd);
00202             if(null_fd <= 0) return -1;
00203             if(null_fd < 1) return -1;
00204 
00205             /* first finish writing null file */
00206             /* write out the rows stored in memory */
00207             for (row = fcb->min_null_row; 
00208                   row < fcb->null_cur_row; row++)
00209              G__write_null_bits(null_fd, fcb->NULL_ROWS[row - fcb->min_null_row], 
00210                                                row, fcb->cellhd.cols, fd); 
00211 
00212             /* write missing rows */
00213             if (fcb->open_mode != OPEN_NEW_RANDOM 
00214                 && fcb->null_cur_row < fcb->cellhd.rows)
00215             {
00216                 G__init_null_bits(fcb->null_work_buf, fcb->cellhd.cols);
00217                 for (row = fcb->null_cur_row; row < fcb->cellhd.rows; row++)
00218                       G__write_null_bits(null_fd, fcb->null_work_buf, row, 
00219                                                           fcb->cellhd.cols, fd);
00220             }
00221             close (null_fd);
00222             
00223 #ifdef __MINGW32__
00224             if ( CopyFile ( fcb->null_temp_name, path, FALSE ) == 0 ) {
00225 #else
00226             if(link (fcb->null_temp_name, path) < 0) {
00227 #endif
00228                 if(rename(fcb->null_temp_name, path)) {
00229                     G_warning(_("closecell: can't move %s\nto null file %s"),
00230                                 fcb->null_temp_name, path);
00231                     stat = -1;
00232                 }
00233             } else {
00234                 remove ( fcb->null_temp_name );
00235             }
00236         } else {
00237             remove ( fcb->null_temp_name );
00238             remove ( path );
00239         } /* null_cur_row > 0 */
00240 
00241         if (fcb->open_mode == OPEN_NEW_COMPRESSED) { /* auto compression */
00242             fcb->row_ptr[fcb->cellhd.rows] = lseek (fd, 0L, SEEK_CUR);
00243             G__write_row_ptrs (fd);
00244         }
00245 
00246         if(fcb->map_type != CELL_TYPE) {  /* floating point map */
00247            int cell_fd;
00248 
00249             if (G__write_fp_format(fd) != 0) {
00250                G_warning(_("Error writing floating point format file for map %s"), fcb->name);
00251                stat = -1;
00252             }
00253 
00254             /* now write 0-length cell file */
00255             G__make_mapset_element ("cell");
00256             cell_fd = creat (G__file_name(path, "cell", fcb->name, fcb->mapset), 0666);
00257             close( cell_fd);
00258             strcpy(CELL_DIR, "fcell");
00259        } else {
00260             /* remove fcell/name file */
00261             G__file_name (path, "fcell", fcb->name, fcb->mapset);
00262             remove ( path );
00263             /* remove cell_misc/name/f_format */
00264             sprintf(element,"cell_misc/%s",fcb->name);
00265             G__file_name (path, element, "f_format", fcb->mapset);
00266             remove ( path );
00267             strcpy(CELL_DIR, "cell");
00268             close (fd);
00269        }
00270     } /* ok */
00271     /* NOW CLOSE THE FILE DESCRIPTOR */
00272 
00273     close (fd);
00274     /* remember open_mode */
00275     open_mode = fcb->open_mode;
00276     fcb->open_mode = -1;
00277 
00278     if (fcb->data != NULL)
00279         G_free (fcb->data);
00280 
00281     if (fcb->null_temp_name != NULL)
00282     {
00283         G_free (fcb->null_temp_name);
00284         fcb->null_temp_name = NULL;
00285     }
00286 
00287 /* if the cell file was written to a temporary file
00288  * move this temporary file into the cell file
00289  * if the move fails, tell the user, but go ahead and create
00290  * the support files
00291  */
00292     stat = 1;
00293     if (ok && (fcb->temp_name != NULL)) {
00294         G__file_name (path, CELL_DIR, fcb->name, fcb->mapset);
00295         remove ( path );
00296 #ifdef __MINGW32__
00297         if ( CopyFile ( fcb->temp_name, path, FALSE ) == 0 ) {
00298 #else
00299         if(link (fcb->temp_name, path) < 0) {
00300 #endif
00301             if(rename(fcb->temp_name, path)) {
00302                 G_warning(_("closecell: can't move %s\nto cell file %s"),
00303                             fcb->temp_name, path);
00304                 stat = -1;
00305             }
00306         } else {
00307             remove ( fcb->temp_name );
00308         }
00309     }
00310 
00311     if (fcb->temp_name != NULL) {
00312         G_free (fcb->temp_name);
00313     }
00314 
00315     if (ok) {
00316         /* remove color table */
00317         G_remove_colr (fcb->name);
00318 
00319         /* create a history file */
00320         G_short_history (fcb->name, "raster", &hist);
00321         G_write_history (fcb->name, &hist);
00322 
00323         /* write the range */
00324         if(fcb->map_type == CELL_TYPE) {
00325              G_write_range (fcb->name, &fcb->range);
00326              G__remove_fp_range(fcb->name);
00327         }
00328         /*NOTE: int range for floating point maps is not written out */
00329         else /* if(fcb->map_type != CELL_TYPE) */
00330         {
00331              G_write_fp_range (fcb->name, &fcb->fp_range);
00332              G_construct_default_range(&fcb->range);
00333             /* this range will be used to add default rule to quant structure */
00334         }
00335 
00336         if ( fcb->map_type != CELL_TYPE)
00337            fcb->cellhd.format = -1;
00338         else /* CELL map */
00339            fcb->cellhd.format = fcb->nbytes - 1;
00340 
00341         /* write header file */
00342         G_put_cellhd (fcb->name, &fcb->cellhd);
00343 
00344         /* if map is floating point write the quant rules, otherwise remove f_quant */
00345         if(fcb->map_type != CELL_TYPE) {
00346         /* DEFAULT RANGE QUANT
00347              G_get_fp_range_min_max(&fcb->fp_range, &dcell_min, &dcell_max);
00348              if(!G_is_d_null_value(&dcell_min) && !G_is_d_null_value(&dcell_max))
00349              {
00350                 G_get_range_min_max(&fcb->range, &cell_min, &cell_max);
00351                 G_quant_add_rule(&fcb->quant, dcell_min, dcell_max, 
00352                                              cell_min, cell_max);
00353              }
00354         */
00355              G_quant_round(&fcb->quant);
00356              if( G_write_quant (fcb->name, fcb->mapset, &fcb->quant) < 0)
00357                       G_warning(_("unable to write quant file!"));
00358         } else {
00359             /* remove cell_misc/name/f_quant */
00360             sprintf(element,"cell_misc/%s",fcb->name);
00361             G__file_name (path, element, "f_quant", fcb->mapset);
00362             remove ( path );
00363         }
00364 
00365         /* create empty cats file */
00366        G_get_range_min_max(&fcb->range, &cell_min, &cell_max);
00367        if(G_is_c_null_value(&cell_max)) cell_max = 0;
00368        G_init_cats (cell_max, (char *)NULL, &cats);
00369        G_write_cats (fcb->name, &cats);
00370        G_free_cats (&cats);
00371 
00372         /* write the histogram */
00373         /* only works for integer maps */
00374        if((fcb->map_type == CELL_TYPE)
00375             &&(fcb->want_histogram)) {
00376                     G_write_histogram_cs (fcb->name, &fcb->statf);
00377                     G_free_cell_stats (&fcb->statf);
00378        } else {
00379             G_remove_histogram(fcb->name);
00380        }
00381     } /* OK */
00382 
00383     G_free (fcb->name);
00384     G_free (fcb->mapset);
00385 
00386     for (i=0;i<NULL_ROWS_INMEM;i++)
00387        G_free (fcb->NULL_ROWS[i]);
00388     G_free (fcb->null_work_buf);
00389 
00390     if(fcb->map_type != CELL_TYPE)
00391        G_quant_free(&fcb->quant);
00392 
00393     return stat;
00394 }
00395 
00396 /* returns 0 on success, 1 on failure */
00397 int G__write_fp_format (int fd)
00398 {
00399    struct fileinfo *fcb = &G__.fileinfo[fd];
00400    struct Key_Value *format_kv;
00401    char element[100], path[4096];
00402    int stat;
00403 
00404    if(fcb->map_type == CELL_TYPE)
00405    {
00406        G_warning(_("unable to write f_format file for CELL maps"));
00407        return 0;
00408    }
00409    format_kv = G_create_key_value();
00410    if(fcb->map_type == FCELL_TYPE)
00411        G_set_key_value ("type", "float", format_kv);
00412    else 
00413        G_set_key_value ("type", "double", format_kv);
00414 
00415    G_set_key_value ("byte_order", "xdr", format_kv);
00416 
00417    if (fcb->open_mode == OPEN_NEW_COMPRESSED)
00418       G_set_key_value ("lzw_compression_bits", "-1", format_kv);
00419 
00420    sprintf(element,"cell_misc/%s",fcb->name);
00421    G__file_name(path,element,FORMAT_FILE,fcb->mapset);
00422 
00423    G__make_mapset_element(element);
00424    G_write_key_value_file (path, format_kv, &stat);
00425 
00426    G_free_key_value(format_kv);
00427 
00428    return stat;
00429 }

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