00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00128
00129
00130
00131
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
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
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
00206
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
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 }
00240
00241 if (fcb->open_mode == OPEN_NEW_COMPRESSED) {
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) {
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
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
00261 G__file_name (path, "fcell", fcb->name, fcb->mapset);
00262 remove ( path );
00263
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 }
00271
00272
00273 close (fd);
00274
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
00288
00289
00290
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
00317 G_remove_colr (fcb->name);
00318
00319
00320 G_short_history (fcb->name, "raster", &hist);
00321 G_write_history (fcb->name, &hist);
00322
00323
00324 if(fcb->map_type == CELL_TYPE) {
00325 G_write_range (fcb->name, &fcb->range);
00326 G__remove_fp_range(fcb->name);
00327 }
00328
00329 else
00330 {
00331 G_write_fp_range (fcb->name, &fcb->fp_range);
00332 G_construct_default_range(&fcb->range);
00333
00334 }
00335
00336 if ( fcb->map_type != CELL_TYPE)
00337 fcb->cellhd.format = -1;
00338 else
00339 fcb->cellhd.format = fcb->nbytes - 1;
00340
00341
00342 G_put_cellhd (fcb->name, &fcb->cellhd);
00343
00344
00345 if(fcb->map_type != CELL_TYPE) {
00346
00347
00348
00349
00350
00351
00352
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
00360 sprintf(element,"cell_misc/%s",fcb->name);
00361 G__file_name (path, element, "f_quant", fcb->mapset);
00362 remove ( path );
00363 }
00364
00365
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
00373
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 }
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
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 }