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