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