GRASS GIS 7 Programmer's Manual  7.5.svn(2018)-r72741
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
raster/open.c
Go to the documentation of this file.
1 /*!
2  * \file lib/raster/open.c
3  *
4  * \brief Raster Library - Open raster file
5  *
6  * (C) 1999-2009 by the GRASS Development Team
7  *
8  * This program is free software under the GNU General Public
9  * License (>=v2). Read the file COPYING that comes with GRASS
10  * for details.
11  *
12  * \author USACERL and many others
13  */
14 
15 #include <unistd.h>
16 #include <string.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <errno.h>
21 
22 #include <grass/config.h>
23 #include <grass/gis.h>
24 #include <grass/raster.h>
25 #include <grass/glocale.h>
26 
27 #include "R.h"
28 #define FORMAT_FILE "f_format"
29 #define NULL_FILE "null"
30 /* cmpressed null file */
31 #define NULLC_FILE "nullcmpr"
32 
33 static int new_fileinfo(void)
34 {
35  int oldsize = R__.fileinfo_count;
36  int newsize = oldsize;
37  int i;
38 
39  for (i = 0; i < oldsize; i++)
40  if (R__.fileinfo[i].open_mode <= 0) {
41  memset(&R__.fileinfo[i], 0, sizeof(struct fileinfo));
42  R__.fileinfo[i].open_mode = -1;
43  return i;
44  }
45 
46  if (newsize < 20)
47  newsize += 20;
48  else
49  newsize *= 2;
50 
51  R__.fileinfo = G_realloc(R__.fileinfo, newsize * sizeof(struct fileinfo));
52 
53  /* Mark all cell files as closed */
54  for (i = oldsize; i < newsize; i++) {
55  memset(&R__.fileinfo[i], 0, sizeof(struct fileinfo));
56  R__.fileinfo[i].open_mode = -1;
57  }
58 
59  R__.fileinfo_count = newsize;
60 
61  return oldsize;
62 }
63 
64 /*!
65  * \brief Open raster file
66  *
67  * Arrange for the NULL-value bitmap to be read as well as the raster
68  * map. If no NULL-value bitmap exists, arrange for the production of
69  * NULL-values based on zeros in the raster map. If the map is
70  * floating-point, arrange for quantization to integer for
71  * Rast_get_c_row(), et. al., by reading the quantization rules
72  * for the map using Rast_read_quant(). If the programmer wants to read
73  * the floating point map using uing quant rules other than the ones
74  * stored in map's quant file, he/she should call Rast_set_quant_rules()
75  * after the call to Rast_open_old().
76  *
77  * \param name map name
78  * \param open_mode mode
79  * \param map_type map type (CELL, FCELL, DCELL)
80  *
81  * \return open file descriptor ( >= 0) if successful
82  */
83 
84 static int open_raster_new(const char *name, int open_mode,
85  RASTER_MAP_TYPE map_type);
86 
87 /*!
88  \brief Open an existing integer raster map (cell)
89 
90  Opens the existing cell file <i>name</i> in the <i>mapset</i> for
91  reading by Rast_get_row() with mapping into the current window.
92 
93  This routine opens the raster map <i>name</i> in <i>mapset</i> for
94  reading. A nonnegative file descriptor is returned if the open is
95  successful. Otherwise a diagnostic message is printed and a negative
96  value is returned. This routine does quite a bit of work. Since
97  GRASS users expect that all raster maps will be resampled into the
98  current region, the resampling index for the raster map is prepared
99  by this routine after the file is opened. The resampling is based on
100  the active module region (see also \ref The_Region}. Preparation
101  required for reading the various raster file formats (see \ref
102  Raster_File_Format for an explanation of the various raster file
103  formats) is also done.
104 
105  Diagnostics: warning message printed if open fails.
106 
107  \param name map name
108  \param mapset mapset name where raster map <i>name</i> lives
109 
110  \return nonnegative file descriptor (int)
111  */
112 int Rast_open_old(const char *name, const char *mapset)
113 {
114  int fd = Rast__open_old(name, mapset);
115 
116  /* turn on auto masking, if not already on */
118  /*
119  if(R__.auto_mask <= 0)
120  R__.mask_buf = Rast_allocate_c_buf();
121  now we don't ever free it!, so no need to allocate it (Olga)
122  */
123  /* mask_buf is used for reading MASK file when mask is set and
124  for reading map rows when the null file doesn't exist */
125 
126  return fd;
127 }
128 
129 /*! \brief Lower level function, open cell files, supercell files,
130  and the MASK file.
131 
132  Actions:
133  - opens the named cell file, following reclass reference if
134  named layer is a reclass layer.
135  - creates the required mapping between the data and the window
136  for use by the get_map_row family of routines.
137 
138  Diagnostics: Errors other than actual open failure will cause a
139  diagnostic to be delivered through G_warning() open failure messages
140  are left to the calling routine since the masking logic will want to
141  issue a different warning.
142 
143  Note: This routine does NOT open the MASK layer. If it did we would
144  get infinite recursion. This routine is called to open the mask by
145  Rast__check_for_auto_masking() which is called by Rast_open_old().
146 
147  \param name map name
148  \param mapset mapset of cell file to be opened
149 
150  \return open file descriptor
151  */
152 int Rast__open_old(const char *name, const char *mapset)
153 {
154  struct fileinfo *fcb;
155  int cell_fd, fd;
156  char *cell_dir;
157  const char *r_name;
158  const char *r_mapset;
159  struct Cell_head cellhd;
160  int CELL_nbytes = 0; /* bytes per cell in CELL map */
161  int INTERN_SIZE;
162  int reclass_flag;
163  int MAP_NBYTES;
164  RASTER_MAP_TYPE MAP_TYPE;
165  struct Reclass reclass;
166  char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
167  struct GDAL_link *gdal;
168 
169  Rast__init();
170 
171  G_unqualified_name(name, mapset, xname, xmapset);
172  name = xname;
173  mapset = xmapset;
174 
175  if (!G_find_raster2(name, mapset))
176  G_fatal_error(_("Raster map <%s> not found"),
177  G_fully_qualified_name(name, mapset));
178 
179  /* Check for reclassification */
180  reclass_flag = Rast_get_reclass(name, mapset, &reclass);
181 
182  switch (reclass_flag) {
183  case 0:
184  r_name = name;
185  r_mapset = mapset;
186  break;
187  case 1:
188  r_name = reclass.name;
189  r_mapset = reclass.mapset;
190  if (!G_find_raster2(r_name, r_mapset))
191  G_fatal_error(_("Unable to open raster map <%s@%s> since it is a reclass "
192  "of raster map <%s@%s> which does not exist"),
193  name, mapset, r_name, r_mapset);
194  break;
195  default: /* Error reading cellhd/reclass file */
196  G_fatal_error(_("Error reading reclass file for raster map <%s>"),
197  G_fully_qualified_name(name, mapset));
198  break;
199  }
200 
201  /* read the cell header */
202  Rast_get_cellhd(r_name, r_mapset, &cellhd);
203 
204  /* now check the type */
205  MAP_TYPE = Rast_map_type(r_name, r_mapset);
206  if (MAP_TYPE < 0)
207  G_fatal_error(_("Error reading map type for raster map <%s>"),
208  G_fully_qualified_name(name, mapset));
209 
210  if (MAP_TYPE == CELL_TYPE)
211  /* set the number of bytes for CELL map */
212  {
213  CELL_nbytes = cellhd.format + 1;
214  if (CELL_nbytes < 1)
215  G_fatal_error(_("Raster map <%s@%s>: format field in header file invalid"),
216  r_name, r_mapset);
217  }
218 
219  /* compressor */
220  if (MAP_TYPE != CELL_TYPE) {
221  /* fp maps do not use RLE */
222  /* previously, compressed simply meant yes (ZLIB) or no
223  * now compressed encodes compressor type
224  * 0: not compressed
225  * 1, 2: ZLIB
226  * 3: LZ4
227  * 4: BZIP2
228  * etc */
229  if (cellhd.compressed == 1)
230  cellhd.compressed = 2;
231  }
232  /* test if compressor type is supported */
233  if (!G_check_compressor(cellhd.compressed)) {
234  G_fatal_error(_("Compression with %s is not supported"), G_compressor_name(cellhd.compressed));
235  }
236 
237  if (cellhd.proj != R__.rd_window.proj)
238  G_fatal_error(_("Raster map <%s> is in different projection than current region. "
239  "Found <%s>, should be <%s>."),
240  G_fully_qualified_name(name, mapset),
241  G_projection_name(cellhd.proj),
243 
244  if (cellhd.zone != R__.rd_window.zone)
245  G_fatal_error(_("Raster map <%s> is in different zone (%d) than current region (%d)"),
246  G_fully_qualified_name(name, mapset), cellhd.zone, R__.rd_window.zone);
247 
248  /* when map is int warn if too large cell size */
249  if (MAP_TYPE == CELL_TYPE && (unsigned int)CELL_nbytes > sizeof(CELL))
250  G_fatal_error(_("Raster map <%s>: bytes per cell (%d) too large"),
251  G_fully_qualified_name(name, mapset), CELL_nbytes);
252 
253  /* record number of bytes per cell */
254  if (MAP_TYPE == FCELL_TYPE) {
255  cell_dir = "fcell";
256  INTERN_SIZE = sizeof(FCELL);
257  MAP_NBYTES = XDR_FLOAT_NBYTES;
258  }
259  else if (MAP_TYPE == DCELL_TYPE) {
260  cell_dir = "fcell";
261  INTERN_SIZE = sizeof(DCELL);
262  MAP_NBYTES = XDR_DOUBLE_NBYTES;
263  }
264  else { /* integer */
265  cell_dir = "cell";
266  INTERN_SIZE = sizeof(CELL);
267  MAP_NBYTES = CELL_nbytes;
268  }
269 
270  gdal = Rast_get_gdal_link(r_name, r_mapset);
271  if (gdal) {
272 #ifdef HAVE_GDAL
273  cell_fd = -1;
274 #else
275  G_fatal_error(_("Raster map <%s@%s> is a GDAL link but GRASS is compiled without GDAL support"),
276  r_name, r_mapset);
277 #endif
278  }
279  else {
280  /* now actually open file for reading */
281  cell_fd = G_open_old(cell_dir, r_name, r_mapset);
282  if (cell_fd < 0)
283  G_fatal_error(_("Unable to open %s file for raster map <%s@%s>"),
284  cell_dir, r_name, r_mapset);
285  }
286 
287  fd = new_fileinfo();
288  fcb = &R__.fileinfo[fd];
289  fcb->data_fd = cell_fd;
290 
291  fcb->map_type = MAP_TYPE;
292 
293  /* Save cell header */
294  fcb->cellhd = cellhd;
295 
296  /* allocate null bitstream buffers for reading null rows */
297  fcb->null_fd = -1;
298  fcb->null_cur_row = -1;
299  fcb->null_bits = Rast__allocate_null_bits(cellhd.cols);
300 
301  /* mark closed */
302  fcb->open_mode = -1;
303 
304  /* save name and mapset */
305  fcb->name = G_store(name);
306  fcb->mapset = G_store(mapset);
307 
308  /* mark no data row in memory */
309  fcb->cur_row = -1;
310 
311  /* if reclass, copy reclass structure */
312  if ((fcb->reclass_flag = reclass_flag))
313  fcb->reclass = reclass;
314 
315  fcb->gdal = gdal;
316  if (!gdal)
317  /* check for compressed data format, making initial reads if necessary */
318  if (Rast__check_format(fd) < 0) {
319  close(cell_fd); /* warning issued by check_format() */
320  G_fatal_error(_("Error reading format for <%s@%s>"),
321  r_name, r_mapset);
322  }
323 
324  /* create the mapping from cell file to window */
326 
327  /*
328  * allocate the data buffer
329  * number of bytes per cell is cellhd.format+1
330  */
331 
332  /* for reading fcb->data is allocated to be fcb->cellhd.cols * fcb->nbytes
333  (= XDR_FLOAT/DOUBLE_NBYTES) */
334  fcb->data = (unsigned char *)G_calloc(fcb->cellhd.cols, MAP_NBYTES);
335 
336  /* initialize/read in quant rules for float point maps */
337  if (fcb->map_type != CELL_TYPE) {
338  if (fcb->reclass_flag)
340  &(fcb->quant));
341  else
342  Rast_read_quant(fcb->name, fcb->mapset, &(fcb->quant));
343  }
344 
345  /* now mark open for read: this must follow create_window_mapping() */
346  fcb->open_mode = OPEN_OLD;
347  fcb->io_error = 0;
348  fcb->map_type = MAP_TYPE;
349  fcb->nbytes = MAP_NBYTES;
350  fcb->null_row_ptr = NULL;
351 
352  if (!gdal) {
353  /* First, check for compressed null file */
354  fcb->null_fd = G_open_old_misc("cell_misc", NULL_FILE, r_name, r_mapset);
355  if (fcb->null_fd < 0) {
356  fcb->null_fd = G_open_old_misc("cell_misc", NULLC_FILE, r_name, r_mapset);
357  if (fcb->null_fd >= 0) {
358  fcb->null_row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
359  if (Rast__read_null_row_ptrs(fd, fcb->null_fd) < 0) {
360  close(fcb->null_fd);
361  fcb->null_fd = -1;
362  G_free(fcb->null_row_ptr);
363  fcb->null_row_ptr = NULL;
364  }
365  }
366  }
367  fcb->null_file_exists = fcb->null_fd >= 0;
368  }
369 
370  return fd;
371 }
372 
373 /*!
374  \brief Opens a new cell file in a database (compressed)
375 
376  Opens a new cell file <i>name</i> in the current mapset for writing
377  by Rast_put_row().
378 
379  The file is created and filled with no data it is assumed that the
380  new cell file is to conform to the current window.
381 
382  The file must be written sequentially. Use Rast_open_new_random()
383  for non sequential writes.
384 
385  Note: the open actually creates a temporary file Rast_close() will
386  move the temporary file to the cell file and write out the necessary
387  support files (cellhd, cats, hist, etc.).
388 
389  Diagnostics: warning message printed if open fails
390 
391  Warning: calls to Rast_set_window() made after opening a new cell file
392  may create confusion and should be avoided the new cell file will be
393  created to conform to the window at the time of the open.
394 
395  \param name map name
396 
397  \return open file descriptor ( >= 0) if successful
398  \return negative integer if error
399  */
400 int Rast_open_c_new(const char *name)
401 {
402  return open_raster_new(name, OPEN_NEW_COMPRESSED, CELL_TYPE);
403 }
404 
405 /*!
406  \brief Opens a new cell file in a database (uncompressed)
407 
408  See also Rast_open_new().
409 
410  \param name map name
411 
412  \return open file descriptor ( >= 0) if successful
413  \return negative integer if error
414  */
416 {
417  return open_raster_new(name, OPEN_NEW_UNCOMPRESSED, CELL_TYPE);
418 }
419 
420 /*!
421  \brief Save histogram for newly create raster map (cell)
422 
423  If newly created cell files should have histograms, set flag=1
424  otherwise set flag=0. Applies to subsequent opens.
425 
426  \param flag flag indicator
427  */
428 void Rast_want_histogram(int flag)
429 {
430  R__.want_histogram = flag;
431 }
432 
433 /*!
434  \brief Sets the format for subsequent opens on new integer cell files
435  (uncompressed and random only).
436 
437  Warning: subsequent put_row calls will only write n+1 bytes per
438  cell. If the data requires more, the cell file will be written
439  incorrectly (but with n+1 bytes per cell)
440 
441  When writing float map: format is -1
442 
443  \param n format
444  */
446 /* sets the format for integer raster map */
447 {
448  R__.nbytes = n + 1;
449  if (R__.nbytes <= 0)
450  R__.nbytes = 1;
451  if (R__.nbytes > sizeof(CELL))
452  R__.nbytes = sizeof(CELL);
453 }
454 
455 /*!
456  \brief Get cell value format
457 
458  \param v cell
459 
460  \return cell format
461  */
463 {
464  unsigned int i;
465 
466  if (v >= 0)
467  for (i = 0; i < sizeof(CELL); i++)
468  if (!(v /= 256))
469  return i;
470  return sizeof(CELL) - 1;
471 }
472 
473 /*!
474  \brief Opens new fcell file in a database
475 
476  Opens a new floating-point map <i>name</i> in the current mapset for
477  writing. The type of the file (i.e. either double or float) is
478  determined and fixed at this point. The default is FCELL_TYPE. In
479  order to change this default
480 
481  Use Rast_set_fp_type() where type is one of DCELL_TYPE or FCELL_TYPE.
482 
483  See warnings and notes for Rast_open_new().
484 
485  \param name map name
486 
487  \return nonnegative file descriptor (int)
488  */
489 int Rast_open_fp_new(const char *name)
490 {
491  return open_raster_new(name, OPEN_NEW_COMPRESSED, R__.fp_type);
492 }
493 
494 /*!
495  \brief Opens new fcell file in a database (uncompressed)
496 
497  See Rast_open_fp_new() for details.
498 
499  \param name map name
500 
501  \return nonnegative file descriptor (int)
502  */
504 {
505  return open_raster_new(name, OPEN_NEW_UNCOMPRESSED, R__.fp_type);
506 }
507 
508 #ifdef HAVE_GDAL
509 static int open_raster_new_gdal(char *map, char *mapset,
510  RASTER_MAP_TYPE map_type)
511 {
512  int fd;
513  struct fileinfo *fcb;
514 
515  fd = new_fileinfo();
516  fcb = &R__.fileinfo[fd];
517  fcb->data_fd = -1;
518 
519  /* mark closed */
520  fcb->map_type = map_type;
521  fcb->open_mode = -1;
522 
523  fcb->gdal = Rast_create_gdal_link(map, map_type);
524  if (!fcb->gdal)
525  G_fatal_error(_("Unable to create GDAL link"));
526 
527  fcb->cellhd = R__.wr_window;
528  fcb->cellhd.compressed = 0;
529  fcb->nbytes = Rast_cell_size(fcb->map_type);
530  /* for writing fcb->data is allocated to be R__.wr_window.cols *
531  sizeof(CELL or DCELL or FCELL) */
532  fcb->data = G_calloc(R__.wr_window.cols, fcb->nbytes);
533 
534  fcb->name = map;
535  fcb->mapset = mapset;
536  fcb->cur_row = 0;
537 
538  fcb->row_ptr = NULL;
539  fcb->temp_name = NULL;
540  fcb->null_temp_name = NULL;
541  fcb->null_cur_row = 0;
542  fcb->null_bits = NULL;
543  fcb->null_fd = -1;
544  fcb->null_row_ptr = NULL;
545 
546  if (fcb->map_type != CELL_TYPE)
547  Rast_quant_init(&(fcb->quant));
548 
549  /* init cell stats */
550  /* now works only for int maps */
551  if (fcb->map_type == CELL_TYPE)
552  if ((fcb->want_histogram = R__.want_histogram))
554 
555  /* init range and if map is double/float init d/f_range */
556  Rast_init_range(&fcb->range);
557 
558  if (fcb->map_type != CELL_TYPE)
560 
561  /* mark file as open for write */
563  fcb->io_error = 0;
564 
565  return fd;
566 }
567 #endif /* HAVE_GDAL */
568 
569 static int open_raster_new(const char *name, int open_mode,
570  RASTER_MAP_TYPE map_type)
571 {
572  char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
573  struct fileinfo *fcb;
574  int fd, cell_fd;
575  char *tempname;
576  char *map;
577  char *mapset;
578  const char *cell_dir;
579  int nbytes;
580 
581  Rast__init();
582 
583  switch (map_type) {
584  case CELL_TYPE:
585  cell_dir = "cell";
586  nbytes = R__.nbytes;
587  break;
588  case FCELL_TYPE:
589  nbytes = XDR_FLOAT_NBYTES;
590  cell_dir = "fcell";
591  break;
592  case DCELL_TYPE:
593  nbytes = XDR_DOUBLE_NBYTES;
594  cell_dir = "fcell";
595  break;
596  default:
597  G_fatal_error(_("Invalid map type <%d>"), map_type);
598  break;
599  }
600 
601  if (G_unqualified_name(name, G_mapset(), xname, xmapset) < 0)
602  G_fatal_error(_("Raster map <%s> is not in the current mapset (%s)"),
603  name, G_mapset());
604  map = G_store(xname);
605  mapset = G_store(xmapset);
606 
607  /* check for legal grass name */
608  if (G_legal_filename(map) < 0)
609  G_fatal_error(_("<%s> is an illegal file name"), map);
610 
611 #ifdef HAVE_GDAL
612  if (G_find_file2("", "GDAL", G_mapset()))
613  return open_raster_new_gdal(map, mapset, map_type);
614 #endif
615 
616  /* open a tempfile name */
617  tempname = G_tempfile();
618  cell_fd = creat(tempname, 0666);
619  if (cell_fd < 0) {
620  int err = errno;
621  G_free(mapset);
622  G_free(tempname);
623  G_free(map);
624  G_fatal_error(_("No temp files available: %s"), strerror(err));
625  }
626 
627  fd = new_fileinfo();
628  fcb = &R__.fileinfo[fd];
629  fcb->data_fd = cell_fd;
630 
631  /*
632  * since we are bypassing the normal open logic
633  * must create the cell element
634  */
635  G_make_mapset_element(cell_dir);
636 
637  /* mark closed */
638  fcb->map_type = map_type;
639  fcb->open_mode = -1;
640  fcb->gdal = NULL;
641 
642  /* for writing fcb->data is allocated to be R__.wr_window.cols *
643  sizeof(CELL or DCELL or FCELL) */
644  fcb->data = (unsigned char *)G_calloc(R__.wr_window.cols,
645  Rast_cell_size(fcb->map_type));
646 
647  /*
648  * copy current window into cell header
649  * set format to cell/supercell
650  * for compressed writing
651  * allocate space to hold the row address array
652  */
653  fcb->cellhd = R__.wr_window;
654 
655  /* change open_mode to OPEN_NEW_UNCOMPRESSED if R__.compression_type == 0 ? */
656 
657  if (open_mode == OPEN_NEW_COMPRESSED && fcb->map_type == CELL_TYPE) {
658  fcb->row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
659  G_zero(fcb->row_ptr, (fcb->cellhd.rows + 1) * sizeof(off_t));
662 
663  fcb->nbytes = 1; /* to the minimum */
664  }
665  else {
666  fcb->nbytes = nbytes;
667  if (open_mode == OPEN_NEW_COMPRESSED) {
668  fcb->row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
669  G_zero(fcb->row_ptr, (fcb->cellhd.rows + 1) * sizeof(off_t));
672  }
673  else
674  fcb->cellhd.compressed = 0;
675 
676  if (fcb->map_type != CELL_TYPE) {
677  Rast_quant_init(&(fcb->quant));
678  }
679  }
680  if (open_mode == OPEN_NEW_COMPRESSED && fcb->map_type != CELL_TYPE &&
681  fcb->cellhd.compressed == 1) {
682  /* fp maps do not use RLE */
683  fcb->cellhd.compressed = 2;
684  }
685 
686  /* save name and mapset, and tempfile name */
687  fcb->name = map;
688  fcb->mapset = mapset;
689  fcb->temp_name = tempname;
690 
691  /* next row to be written (in order) is zero */
692  fcb->cur_row = 0;
693 
694  /* open a null tempfile name */
695  tempname = G_tempfile();
696  fcb->null_fd = creat(tempname, 0666);
697  if (fcb->null_fd < 0) {
698  int err = errno;
699  G_free(tempname);
700  G_free(fcb->name);
701  G_free(fcb->mapset);
702  G_free(fcb->temp_name);
703  close(cell_fd);
704  G_fatal_error(_("No temp files available: %s"), strerror(err));
705  }
706 
707  fcb->null_temp_name = tempname;
708 
709  fcb->null_row_ptr = NULL;
710  if (R__.compress_nulls) {
711  fcb->null_row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
712  G_zero(fcb->null_row_ptr, (fcb->cellhd.rows + 1) * sizeof(off_t));
714  }
715 
716  /* next row to be written (in order) is zero */
717  fcb->null_cur_row = 0;
718 
719  /* allocate null bitstream buffer for writing */
721 
722  /* init cell stats */
723  /* now works only for int maps */
724  if (fcb->map_type == CELL_TYPE)
725  if ((fcb->want_histogram = R__.want_histogram))
727 
728  /* init range and if map is double/float init d/f_range */
729  Rast_init_range(&fcb->range);
730 
731  if (fcb->map_type != CELL_TYPE)
733 
734  /* mark file as open for write */
735  fcb->open_mode = open_mode;
736  fcb->io_error = 0;
737 
738  return fd;
739 }
740 
741 int Rast__open_null_write(const char *name)
742 {
743  char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
744  struct fileinfo *fcb;
745  int fd;
746  char *tempname;
747  char *map;
748  char *mapset;
749 
750  Rast__init();
751 
752  if (!G_find_raster2(name, G_mapset()))
753  G_fatal_error(_("Raster map <%s> does not exist in the current mapset (%s)"),
754  name, G_mapset());
755 
756  if (G_unqualified_name(name, G_mapset(), xname, xmapset) < 0)
757  G_fatal_error(_("Raster map <%s> is not in the current mapset (%s)"),
758  name, G_mapset());
759  map = G_store(xname);
760  mapset = G_store(xmapset);
761 
762  fd = new_fileinfo();
763  fcb = &R__.fileinfo[fd];
764 
765  G_zero(fcb, sizeof(*fcb));
766 
767  fcb->name = map;
768  fcb->mapset = mapset;
769 
770  Rast_get_cellhd(map, mapset, &fcb->cellhd);
771 
772  /* open a null tempfile name */
773  tempname = G_tempfile();
774  fcb->null_fd = creat(tempname, 0666);
775  if (fcb->null_fd < 0) {
776  int err = errno;
777  G_free(tempname);
778  G_free(fcb->name);
779  G_free(fcb->mapset);
780  G_fatal_error(_("No temp files available: %s"), strerror(err));
781  }
782  fcb->null_temp_name = tempname;
783 
784  if (R__.compress_nulls) {
785  fcb->null_row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
786  G_zero(fcb->null_row_ptr, (fcb->cellhd.rows + 1) * sizeof(off_t));
788  }
789 
790  /* allocate null bitstream buffer for writing */
792 
793  return fd;
794 }
795 
796 /*!
797  \brief Set raster map floating-point data format.
798 
799  This controls the storage type for floating-point maps. It affects
800  subsequent calls to G_open_fp_map_new(). The <i>type</i> must be
801  one of FCELL_TYPE (float) or DCELL_TYPE (double). The use of this
802  routine by applications is discouraged since its use would override
803  user preferences.
804 
805  \param type raster data type
806 
807  \return void
808  */
810 {
811  Rast__init();
812 
813  switch (map_type) {
814  case FCELL_TYPE:
815  case DCELL_TYPE:
816  R__.fp_type = map_type;
817  break;
818  default:
819  G_fatal_error(_("Rast_set_fp_type(): can only be called with FCELL_TYPE or DCELL_TYPE"));
820  break;
821  }
822 }
823 
824 /*!
825  \brief Check if raster map is floating-point
826 
827  Returns true (1) if raster map <i>name</i> in <i>mapset</i>
828  is a floating-point dataset; false(0) otherwise.
829 
830  \param name map name
831  \param mapset mapset name
832 
833  \return 1 floating-point
834  \return 0 int
835  */
836 int Rast_map_is_fp(const char *name, const char *mapset)
837 {
838  char path[GPATH_MAX];
839  const char *xmapset;
840 
841  xmapset = G_find_raster2(name, mapset);
842  if (!xmapset)
843  G_fatal_error(_("Raster map <%s> not found"),
844  G_fully_qualified_name(name, mapset));
845 
846  G_file_name(path, "fcell", name, xmapset);
847  if (access(path, 0) == 0)
848  return 1;
849 
850  G_file_name(path, "g3dcell", name, xmapset);
851  if (access(path, 0) == 0)
852  return 1;
853 
854  return 0;
855 }
856 
857 /*!
858  \brief Determine raster data type
859 
860  Determines if the raster map is floating point or integer. Returns
861  DCELL_TYPE for double maps, FCELL_TYPE for float maps, CELL_TYPE for
862  integer maps, -1 if error has occurred
863 
864  \param name map name
865  \param mapset mapset where map <i>name</i> lives
866 
867  \return raster data type
868  */
869 RASTER_MAP_TYPE Rast_map_type(const char *name, const char *mapset)
870 {
871  char path[GPATH_MAX];
872  const char *xmapset;
873 
874  xmapset = G_find_raster2(name, mapset);
875  if (!xmapset) {
876  if (mapset && *mapset)
877  G_fatal_error(_("Raster map <%s> not found in mapset <%s>"),
878  name, mapset);
879  else
880  G_fatal_error(_("Raster map <%s> not found"), name);
881  }
882 
883  G_file_name(path, "fcell", name, xmapset);
884 
885  if (access(path, 0) == 0)
886  return Rast__check_fp_type(name, xmapset);
887 
888  G_file_name(path, "g3dcell", name, xmapset);
889 
890  if (access(path, 0) == 0)
891  return DCELL_TYPE;
892 
893  return CELL_TYPE;
894 }
895 
896 /*!
897  \brief Determine raster type from descriptor
898 
899  Determines if the raster map is floating point or integer. Returns
900  DCELL_TYPE for double maps, FCELL_TYPE for float maps, CELL_TYPE for
901  integer maps, -1 if error has occurred
902 
903  \param fd file descriptor
904 
905  \return raster data type
906  */
908 {
909  struct fileinfo *fcb = &R__.fileinfo[fd];
910 
911  return fcb->map_type;
912 }
913 
914 /*!
915  \brief Determines whether the floating points cell file has double or float type
916 
917  \param name map name
918  \param mapset mapset where map <i>name</i> lives
919 
920  \return raster type (fcell, dcell)
921  */
922 RASTER_MAP_TYPE Rast__check_fp_type(const char *name, const char *mapset)
923 {
924  char path[GPATH_MAX];
925  struct Key_Value *format_keys;
926  const char *str, *str1;
927  RASTER_MAP_TYPE map_type;
928  const char *xmapset;
929 
930  xmapset = G_find_raster2(name, mapset);
931  if (!xmapset)
932  G_fatal_error(_("Raster map <%s> not found"),
933  G_fully_qualified_name(name, mapset));
934 
935  G_file_name_misc(path, "cell_misc", FORMAT_FILE, name, xmapset);
936 
937  if (access(path, 0) != 0)
938  G_fatal_error(_("Unable to find '%s'"), path);
939 
940  format_keys = G_read_key_value_file(path);
941 
942  if ((str = G_find_key_value("type", format_keys)) != NULL) {
943  if (strcmp(str, "double") == 0)
944  map_type = DCELL_TYPE;
945  else if (strcmp(str, "float") == 0)
946  map_type = FCELL_TYPE;
947  else {
948  G_free_key_value(format_keys);
949  G_fatal_error(_("Invalid type: field '%s' in file '%s'"), str, path);
950  }
951  }
952  else {
953  G_free_key_value(format_keys);
954  G_fatal_error(_("Missing type: field in file '%s'"), path);
955  }
956 
957  if ((str1 = G_find_key_value("byte_order", format_keys)) != NULL) {
958  if (strcmp(str1, "xdr") != 0)
959  G_warning(_("Raster map <%s> is not xdr: byte_order: %s"),
960  name, str);
961  /* here read and translate byte order if not using xdr */
962  }
963  G_free_key_value(format_keys);
964  return map_type;
965 }
966 
967 /*!
968  \brief Opens a new raster map
969 
970  Opens a new raster map of type <i>wr_type</i>
971 
972  See warnings and notes for Rast_open_new().
973 
974  Supported data types:
975  - CELL_TYPE
976  - FCELL_TYPE
977  - DCELL_TYPE
978 
979  On CELL_TYPE calls Rast_open_new() otherwise Rast_open_fp_new().
980 
981  \param name map name
982  \param wr_type raster data type
983 
984  \return nonnegative file descriptor (int)
985  */
986 int Rast_open_new(const char *name, RASTER_MAP_TYPE wr_type)
987 {
988  return open_raster_new(name, OPEN_NEW_COMPRESSED, wr_type);
989 }
990 
991 /*!
992  \brief Opens a new raster map (uncompressed)
993 
994  See Rast_open_new().
995 
996  \param name map name
997  \param wr_type raster data type
998 
999  \return nonnegative file descriptor (int)
1000  */
1001 int Rast_open_new_uncompressed(const char *name, RASTER_MAP_TYPE wr_type)
1002 {
1003  return open_raster_new(name, OPEN_NEW_UNCOMPRESSED, wr_type);
1004 }
1005 
1006 /*!
1007  \brief Sets quant translation rules for raster map opened for
1008  reading.
1009 
1010  Returned by Rast_open_old(). After calling this function,
1011  Rast_get_c_row() and Rast_get_c_row() will use rules defined by q
1012  (instead of using rules defined in map's quant file) to convert floats to
1013  ints.
1014 
1015  \param fd file descriptor (cell file)
1016  \param q pointer to Quant structure
1017 
1018  \return void
1019  */
1020 void Rast_set_quant_rules(int fd, struct Quant *q)
1021 {
1022  struct fileinfo *fcb = &R__.fileinfo[fd];
1023  CELL cell;
1024  DCELL dcell;
1025  struct Quant_table *p;
1026 
1027  if (fcb->open_mode != OPEN_OLD)
1028  G_fatal_error(_("Rast_set_quant_rules() can be called only for "
1029  "raster maps opened for reading"));
1030 
1031  /* copy all info from q to fcb->quant) */
1032  Rast_quant_init(&fcb->quant);
1033  if (q->truncate_only) {
1034  Rast_quant_truncate(&fcb->quant);
1035  return;
1036  }
1037 
1038  for (p = &(q->table[q->nofRules - 1]); p >= q->table; p--)
1039  Rast_quant_add_rule(&fcb->quant, p->dLow, p->dHigh, p->cLow,
1040  p->cHigh);
1041  if (Rast_quant_get_neg_infinite_rule(q, &dcell, &cell) > 0)
1042  Rast_quant_set_neg_infinite_rule(&fcb->quant, dcell, cell);
1043  if (Rast_quant_get_pos_infinite_rule(q, &dcell, &cell) > 0)
1044  Rast_quant_set_pos_infinite_rule(&fcb->quant, dcell, cell);
1045 }
int G_make_mapset_element(const char *p_element)
Create element in the current mapset.
Definition: mapset_msc.c:38
int Rast__check_for_auto_masking(void)
Checks for auto masking.
Definition: auto_mask.c:37
#define CELL_TYPE
Definition: raster.h:11
int Rast__write_null_row_ptrs(int fd, int null_fd)
#define OPEN_NEW_COMPRESSED
Definition: R.h:93
struct Cell_head rd_window
Definition: R.h:83
#define NULL_FILE
Definition: raster/open.c:29
int nbytes
Definition: R.h:58
const char * G_find_key_value(const char *key, const struct Key_Value *kv)
Find given key (case sensitive)
Definition: key_value1.c:84
int Rast_quant_get_neg_infinite_rule(const struct Quant *q, DCELL *dLeft, CELL *c)
Returns in &quot;dLeft&quot; and &quot;c&quot; the rule values.
Definition: quant.c:399
int Rast_get_reclass(const char *name, const char *mapset, struct Reclass *reclass)
Get reclass.
Definition: reclass.c:140
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:149
void Rast__create_window_mapping(int fd)
Create window mapping.
char * name
Definition: raster.h:33
int want_histogram
Definition: R.h:47
int Rast_open_fp_new(const char *name)
Opens new fcell file in a database.
Definition: raster/open.c:489
RASTER_MAP_TYPE Rast__check_fp_type(const char *name, const char *mapset)
Determines whether the floating points cell file has double or float type.
Definition: raster/open.c:922
#define GMAPSET_MAX
Definition: gis.h:149
void Rast_quant_truncate(struct Quant *quant)
Sets the quant rules to perform simple truncation on floats.
Definition: quant.c:221
RASTER_MAP_TYPE map_type
Definition: R.h:59
void Rast_set_quant_rules(int fd, struct Quant *q)
Sets quant translation rules for raster map opened for reading.
Definition: raster/open.c:1020
Definition: R.h:72
char * name
Definition: R.h:63
2D/3D raster map header (used also for region)
Definition: gis.h:390
int data_fd
Definition: R.h:68
int Rast__check_format(int fd)
Definition: raster/format.c:63
void Rast_init_cell_stats(struct Cell_stats *s)
Initialize cell stats.
Definition: cell_stats.c:39
off_t * row_ptr
Definition: R.h:49
const char * G_projection_name(int n)
Get projection name.
Definition: proj2.c:55
double DCELL
Definition: gis.h:581
char * G_compressor_name(int number)
Definition: compress.c:118
int io_error
Definition: R.h:65
RASTER_MAP_TYPE fp_type
Definition: R.h:74
void Rast_want_histogram(int flag)
Save histogram for newly create raster map (cell)
Definition: raster/open.c:428
void Rast__init(void)
Definition: raster/init.c:65
int Rast__read_null_row_ptrs(int fd, int null_fd)
char * temp_name
Definition: R.h:60
char * G_store(const char *s)
Copy string to allocated memory.
Definition: strings.c:86
unsigned char * data
Definition: R.h:55
int G_unqualified_name(const char *name, const char *mapset, char *xname, char *xmapset)
Returns unqualified map name (without @ mapset)
Definition: nme_in_mps.c:134
DCELL dHigh
Definition: raster.h:79
char * G_tempfile(void)
Returns a temporary file name.
Definition: tempfile.c:62
int Rast_open_fp_new_uncompressed(const char *name)
Opens new fcell file in a database (uncompressed)
Definition: raster/open.c:503
#define NULLC_FILE
Definition: raster/open.c:31
int Rast_quant_get_pos_infinite_rule(const struct Quant *q, DCELL *dRight, CELL *c)
Returns in &quot;dRight&quot; and &quot;c&quot; the rule values.
Definition: quant.c:447
#define NULL
Definition: ccmath.h:32
unsigned char * null_bits
Definition: R.h:57
struct GDAL_link * gdal
Definition: R.h:67
int format
Max number of bytes per raster data value minus 1 (raster header only)
Definition: gis.h:396
void Rast_quant_add_rule(struct Quant *q, DCELL dLow, DCELL dHigh, CELL cLow, CELL cHigh)
Adds a new rule to the set of quantization rules.
Definition: quant.c:478
struct Range range
Definition: R.h:45
#define OPEN_NEW_UNCOMPRESSED
Definition: R.h:94
void G_free_key_value(struct Key_Value *kv)
Free allocated Key_Value structure.
Definition: key_value1.c:103
struct Reclass reclass
Definition: R.h:43
fd
Definition: d/range.c:69
int truncate_only
Definition: raster.h:86
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:160
int G_open_old_misc(const char *dir, const char *element, const char *name, const char *mapset)
open a database file for reading
Definition: open_misc.c:134
struct Cell_head wr_window
Definition: R.h:84
#define FORMAT_FILE
Definition: raster/open.c:28
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition: symbol/read.c:220
Definition: raster.h:31
struct Key_Value * G_read_key_value_file(const char *file)
Read key/values pairs from file.
Definition: key_value3.c:53
char * G_file_name(char *path, const char *element, const char *name, const char *mapset)
Builds full path names to GIS data files.
Definition: file_name.c:38
CELL cLow
Definition: raster.h:80
int compressed
Compression mode (raster header only)
Definition: gis.h:403
#define DCELL_TYPE
Definition: raster.h:13
size_t Rast_cell_size(RASTER_MAP_TYPE data_type)
Returns size of a raster cell in bytes.
Definition: alloc_cell.c:39
RASTER_MAP_TYPE Rast_map_type(const char *name, const char *mapset)
Determine raster data type.
Definition: raster/open.c:869
void Rast_get_cellhd(const char *name, const char *mapset, struct Cell_head *cellhd)
Read the raster header.
Definition: get_cellhd.c:44
struct GDAL_link * Rast_create_gdal_link(const char *name, RASTER_MAP_TYPE map_type)
Create GDAL settings for given raster map.
Definition: gdal.c:415
struct Cell_stats statf
Definition: R.h:44
void Rast_init_range(struct Range *range)
Initialize range structure.
Definition: range.c:678
struct Quant_table * table
Definition: raster.h:107
Definition: raster.h:84
DCELL dLow
Definition: raster.h:78
int Rast_open_c_new_uncompressed(const char *name)
Opens a new cell file in a database (uncompressed)
Definition: raster/open.c:415
int null_fd
Definition: R.h:56
void Rast_set_cell_format(int n)
Sets the format for subsequent opens on new integer cell files (uncompressed and random only)...
Definition: raster/open.c:445
char * mapset
Definition: R.h:64
int open_mode
Definition: R.h:41
int zone
Projection zone (UTM)
Definition: gis.h:424
int cur_row
Definition: R.h:52
void Rast_set_fp_type(RASTER_MAP_TYPE map_type)
Set raster map floating-point data format.
Definition: raster/open.c:809
int Rast_open_c_new(const char *name)
Opens a new cell file in a database (compressed)
Definition: raster/open.c:400
#define GPATH_MAX
Definition: gis.h:151
#define XDR_DOUBLE_NBYTES
Definition: R.h:8
int proj
Projection code.
Definition: gis.h:422
int fileinfo_count
Definition: R.h:86
struct fileinfo * fileinfo
Definition: R.h:87
char * null_temp_name
Definition: R.h:61
int Rast_read_quant(const char *name, const char *mapset, struct Quant *quant)
Reads quantization rules for name in mapset and stores them in the quantization structure. If the map is in another mapset, first checks for quant2 table for this map in current mapset.
Definition: quant_rw.c:186
Definition: gis.h:479
#define OPEN_OLD
Definition: R.h:92
float FCELL
Definition: gis.h:582
int G_open_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition: gis/open.c:170
int Rast__open_null_write(const char *name)
Definition: raster/open.c:741
int Rast_open_new_uncompressed(const char *name, RASTER_MAP_TYPE wr_type)
Opens a new raster map (uncompressed)
Definition: raster/open.c:1001
RASTER_MAP_TYPE Rast_get_map_type(int fd)
Determine raster type from descriptor.
Definition: raster/open.c:907
int cols
Number of columns for 2D data.
Definition: gis.h:409
int null_file_exists
Definition: R.h:62
int G_check_compressor(int number)
Definition: compress.c:140
int compress_nulls
Definition: R.h:80
off_t * null_row_ptr
Definition: R.h:69
struct Cell_head cellhd
Definition: R.h:42
#define GNAME_MAX
Definition: gis.h:148
int CELL
Definition: gis.h:580
Definition: R.h:39
Definition: path.h:16
#define XDR_FLOAT_NBYTES
Definition: R.h:7
void Rast_quant_init(struct Quant *quant)
Initialize the structure.
Definition: quant.c:179
#define _(str)
Definition: glocale.h:13
int RASTER_MAP_TYPE
Definition: raster.h:25
int null_cur_row
Definition: R.h:53
char * G_fully_qualified_name(const char *name, const char *mapset)
Get fully qualified element name.
Definition: nme_in_mps.c:101
const char * G_find_raster2(const char *name, const char *mapset)
Find a raster map (look but don&#39;t touch)
Definition: find_rast.c:76
#define FCELL_TYPE
Definition: raster.h:12
int Rast_open_new(const char *name, RASTER_MAP_TYPE wr_type)
Opens a new raster map.
Definition: raster/open.c:986
int Rast_map_is_fp(const char *name, const char *mapset)
Check if raster map is floating-point.
Definition: raster/open.c:836
struct Quant quant
Definition: R.h:66
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
close(fd)
char * G_file_name_misc(char *path, const char *dir, const char *element, const char *name, const char *mapset)
Builds full path names to GIS misc data files.
Definition: file_name.c:55
int want_histogram
Definition: R.h:77
void G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:23
int Rast_open_old(const char *name, const char *mapset)
Open an existing integer raster map (cell)
Definition: raster/open.c:112
int nbytes
Definition: R.h:78
const char * name
Definition: named_colr.c:7
unsigned char * Rast__allocate_null_bits(int cols)
Allocates memory for null bits.
Definition: alloc_cell.c:135
char * mapset
Definition: raster.h:34
void Rast_quant_set_pos_infinite_rule(struct Quant *q, DCELL dRight, CELL c)
Defines a rule for values &quot;dRight&quot; and larger.
Definition: quant.c:421
CELL cHigh
Definition: raster.h:81
int nofRules
Definition: raster.h:94
int rows
Number of rows for 2D data.
Definition: gis.h:405
struct FPRange fp_range
Definition: R.h:46
int Rast__write_row_ptrs(int fd)
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
void Rast_quant_set_neg_infinite_rule(struct Quant *q, DCELL dLeft, CELL c)
Defines a rule for values &quot;dLeft&quot; and smaller.
Definition: quant.c:373
const char * G_find_file2(const char *element, const char *name, const char *mapset)
Searches for a file from the mapset search list or in a specified mapset. (look but don&#39;t touch) ...
Definition: find_file.c:247
int Rast__open_old(const char *name, const char *mapset)
Lower level function, open cell files, supercell files, and the MASK file.
Definition: raster/open.c:152
void Rast_init_fp_range(struct FPRange *range)
Initialize fp range.
Definition: range.c:730
struct GDAL_link * Rast_get_gdal_link(const char *name, const char *mapset)
Get GDAL link settings for given raster map.
Definition: gdal.c:237
int Rast_get_cell_format(CELL v)
Get cell value format.
Definition: raster/open.c:462
int compression_type
Definition: R.h:79
int reclass_flag
Definition: R.h:48