00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef __MINGW32__
00025 # include <windows.h>
00026 #endif
00027
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <unistd.h>
00032 #include <fcntl.h>
00033 #include <signal.h>
00034 #include <grass/gis.h>
00035 #include <grass/glocale.h>
00036 #include "G.h"
00037
00038 #define FORMAT_FILE "f_format"
00039 #define QUANT_FILE "f_quant"
00040 #define NULL_FILE "null"
00041
00042 static int close_old(int);
00043 static int close_new(int, int);
00044 static char CELL_DIR[100];
00045
00046
00079 int G_close_cell(int fd)
00080 {
00081 struct fileinfo *fcb = &G__.fileinfo[fd];
00082
00083 if (fd < 0 || fd >= G__.fileinfo_count || fcb->open_mode <= 0)
00084 return -1;
00085 if (fcb->open_mode == OPEN_OLD)
00086 return close_old(fd);
00087
00088 return close_new(fd, 1);
00089 }
00090
00091
00112 int G_unopen_cell(int fd)
00113 {
00114 struct fileinfo *fcb = &G__.fileinfo[fd];
00115
00116 if (fd < 0 || fd >= G__.fileinfo_count || fcb->open_mode <= 0)
00117 return -1;
00118 if (fcb->open_mode == OPEN_OLD)
00119 return close_old(fd);
00120 else
00121 return close_new(fd, 0);
00122 }
00123
00124 static int close_old(int fd)
00125 {
00126 struct fileinfo *fcb = &G__.fileinfo[fd];
00127 int i;
00128
00129
00130
00131
00132
00133
00134
00135
00136 if (fcb->gdal)
00137 G_close_gdal_link(fcb->gdal);
00138
00139 for (i = 0; i < NULL_ROWS_INMEM; i++)
00140 G_free(fcb->NULL_ROWS[i]);
00141 G_free(fcb->null_work_buf);
00142
00143 if (fcb->cellhd.compressed)
00144 G_free(fcb->row_ptr);
00145 G_free(fcb->col_map);
00146 G_free(fcb->mapset);
00147 G_free(fcb->data);
00148 G_free(fcb->name);
00149 if (fcb->reclass_flag)
00150 G_free_reclass(&fcb->reclass);
00151 fcb->open_mode = -1;
00152
00153 if (fcb->map_type != CELL_TYPE) {
00154 G_quant_free(&fcb->quant);
00155 xdr_destroy(&fcb->xdrstream);
00156 }
00157 close(fd);
00158
00159 return 1;
00160 }
00161
00162 static int close_new(int fd, int ok)
00163 {
00164 struct fileinfo *fcb = &G__.fileinfo[fd];
00165 int stat;
00166 struct Categories cats;
00167 struct History hist;
00168 char path[GPATH_MAX];
00169 CELL cell_min, cell_max;
00170 int row, i, open_mode;
00171
00172 if (ok) {
00173 switch (fcb->open_mode) {
00174 case OPEN_NEW_COMPRESSED:
00175 G_debug(1, "close %s compressed", fcb->name);
00176 break;
00177 case OPEN_NEW_UNCOMPRESSED:
00178 G_debug(1, "close %s uncompressed", fcb->name);
00179 break;
00180 case OPEN_NEW_RANDOM:
00181 G_debug(1, "close %s random", fcb->name);
00182 break;
00183 }
00184
00185 if (fcb->open_mode != OPEN_NEW_RANDOM &&
00186 fcb->cur_row < fcb->cellhd.rows) {
00187 G_zero_raster_buf(fcb->data, fcb->map_type);
00188 for (row = fcb->cur_row; row < fcb->cellhd.rows; row++)
00189 G_put_raster_row(fd, fcb->data, fcb->map_type);
00190 G_free(fcb->data);
00191 fcb->data = NULL;
00192 }
00193
00194
00195 G__make_mapset_element_misc("cell_misc", fcb->name);
00196 G__file_name_misc(path, "cell_misc", NULL_FILE, fcb->name,
00197 G_mapset());
00198 remove(path);
00199
00200 if (fcb->null_cur_row > 0) {
00201
00202 int null_fd;
00203
00204 null_fd = G__open_null_write(fd);
00205 if (null_fd <= 0)
00206 return -1;
00207 if (null_fd < 1)
00208 return -1;
00209
00210
00211
00212 for (row = fcb->min_null_row; row < fcb->null_cur_row; row++)
00213 G__write_null_bits(null_fd,
00214 fcb->NULL_ROWS[row - fcb->min_null_row],
00215 row, fcb->cellhd.cols, fd);
00216
00217
00218 if (fcb->open_mode != OPEN_NEW_RANDOM
00219 && fcb->null_cur_row < fcb->cellhd.rows) {
00220 G__init_null_bits(fcb->null_work_buf, fcb->cellhd.cols);
00221 for (row = fcb->null_cur_row; row < fcb->cellhd.rows; row++)
00222 G__write_null_bits(null_fd, fcb->null_work_buf, row,
00223 fcb->cellhd.cols, fd);
00224 }
00225 close(null_fd);
00226
00227 if (rename(fcb->null_temp_name, path)) {
00228 G_warning(_("closecell: can't move %s\nto null file %s"),
00229 fcb->null_temp_name, path);
00230 stat = -1;
00231 }
00232 else {
00233 remove(fcb->null_temp_name);
00234 }
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"),
00251 fcb->name);
00252 stat = -1;
00253 }
00254
00255
00256 G__make_mapset_element("cell");
00257 cell_fd =
00258 creat(G__file_name(path, "cell", fcb->name, fcb->mapset),
00259 0666);
00260 close(cell_fd);
00261 strcpy(CELL_DIR, "fcell");
00262 }
00263 else {
00264
00265 G__file_name(path, "fcell", fcb->name, fcb->mapset);
00266 remove(path);
00267
00268 G__file_name_misc(path, "cell_misc", FORMAT_FILE, fcb->name,
00269 fcb->mapset);
00270 remove(path);
00271 strcpy(CELL_DIR, "cell");
00272 close(fd);
00273 }
00274 }
00275
00276
00277 close(fd);
00278
00279 open_mode = fcb->open_mode;
00280 fcb->open_mode = -1;
00281
00282 if (fcb->data != NULL)
00283 G_free(fcb->data);
00284
00285 if (fcb->null_temp_name != NULL) {
00286 G_free(fcb->null_temp_name);
00287 fcb->null_temp_name = NULL;
00288 }
00289
00290
00291
00292
00293
00294
00295 stat = 1;
00296 if (ok && (fcb->temp_name != NULL)) {
00297 G__file_name(path, CELL_DIR, fcb->name, fcb->mapset);
00298 remove(path);
00299 if (rename(fcb->temp_name, path)) {
00300 G_warning(_("closecell: can't move %s\nto cell file %s"),
00301 fcb->temp_name, path);
00302 stat = -1;
00303 }
00304 else {
00305 remove(fcb->temp_name);
00306 }
00307 }
00308
00309 if (fcb->temp_name != NULL) {
00310 G_free(fcb->temp_name);
00311 }
00312
00313 if (ok) {
00314
00315 G_remove_colors(fcb->name, "");
00316
00317
00318 G_short_history(fcb->name, "raster", &hist);
00319 G_write_history(fcb->name, &hist);
00320
00321
00322 if (fcb->map_type == CELL_TYPE) {
00323 G_write_range(fcb->name, &fcb->range);
00324 G__remove_fp_range(fcb->name);
00325 }
00326
00327 else {
00328
00329 G_write_fp_range(fcb->name, &fcb->fp_range);
00330 G_construct_default_range(&fcb->range);
00331
00332 }
00333
00334 if (fcb->map_type != CELL_TYPE)
00335 fcb->cellhd.format = -1;
00336 else
00337 fcb->cellhd.format = fcb->nbytes - 1;
00338
00339
00340 G_put_cellhd(fcb->name, &fcb->cellhd);
00341
00342
00343 if (fcb->map_type != CELL_TYPE) {
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 G_quant_round(&fcb->quant);
00354 if (G_write_quant(fcb->name, fcb->mapset, &fcb->quant) < 0)
00355 G_warning(_("unable to write quant file!"));
00356 }
00357 else {
00358
00359 G__file_name_misc(path, "cell_misc", QUANT_FILE, fcb->name,
00360 fcb->mapset);
00361 remove(path);
00362 }
00363
00364
00365 G_get_range_min_max(&fcb->range, &cell_min, &cell_max);
00366 if (G_is_c_null_value(&cell_max))
00367 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 }
00379 else {
00380 G_remove_histogram(fcb->name);
00381 }
00382 }
00383
00384 G_free(fcb->name);
00385 G_free(fcb->mapset);
00386
00387 for (i = 0; i < NULL_ROWS_INMEM; i++)
00388 G_free(fcb->NULL_ROWS[i]);
00389 G_free(fcb->null_work_buf);
00390
00391 if (fcb->map_type != CELL_TYPE)
00392 G_quant_free(&fcb->quant);
00393
00394 return stat;
00395 }
00396
00397
00398 int G__write_fp_format(int fd)
00399 {
00400 struct fileinfo *fcb = &G__.fileinfo[fd];
00401 struct Key_Value *format_kv;
00402 char path[GPATH_MAX];
00403 int stat;
00404
00405 if (fcb->map_type == CELL_TYPE) {
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 G__make_mapset_element_misc("cell_misc", fcb->name);
00421 G__file_name_misc(path, "cell_misc", FORMAT_FILE, fcb->name, fcb->mapset);
00422 G_write_key_value_file(path, format_kv, &stat);
00423
00424 G_free_key_value(format_kv);
00425
00426 return stat;
00427 }