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

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