GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
raster/format.c
Go to the documentation of this file.
1#include <unistd.h>
2#include <stdlib.h>
3#include <assert.h>
4
5#include <grass/config.h>
6#include <grass/gis.h>
7#include <grass/raster.h>
8#include <grass/glocale.h>
9
10#include "R.h"
11
12/*!
13
14 <h3>GRASS Raster Format</h3>
15
16 Small example to illustrate the raster format:
17
18 A file may contain the following 3x3 floating point matrix:
19 \verbatim
20 10.000 20.000 30.000
21 20.000 40.000 50.000
22 30.000 50.000 60.000
23 \endverbatim
24
25 The header is a single byte, equal to sizeof(off_t) (typically 4 on a
26 32-bit platform, 8 on a 64-bit platform). Then, NROWS+1 offsets are
27 written as off_t's (i.e. 4 or 8 bytes, depending upon platform) in
28 big-endian (Motorola) byte order.
29 <P>
30 Thus, above example is actually interpreted as:
31 \verbatim
32 4 sizeof(off_t)
33 0 0 0 17 offset of row 0
34 0 0 0 36 offset of row 1
35 0 0 0 55 offset of row 2
36 0 0 0 74 offset of end of data
37 \endverbatim
38
39 See Rast__write_row_ptrs() below for the code which writes this data.
40 However, note that the row offsets are initially zero;
41 they get overwritten later (if you are writing compressed data,
42 you don't know how much space it will require until you've compressed
43 it).
44
45 As for the format of the actual row data, see put_fp_data() in
46 src/libes/gis/put_row.c and RFC 1014 (the XDR specification):
47 http://www.faqs.org/rfcs/rfc1014.html
48
49 */
50
51/**********************************************************************
52 *
53 * Rast__check_format(int fd)
54 *
55 * Check to see if map with file descriptor "fd" is in compressed
56 * format. If it is, the offset table at the beginning of the
57 * file (which gives seek addresses into the file where code for
58 * each row is found) is read into the File Control Buffer (FCB).
59 * The compressed flag in the FCB is appropriately set.
60 *
61 * returns: 1 if row pointers were read successfully, -1 otherwise
62 **********************************************************************/
63
65{
66 struct fileinfo *fcb = &R__.fileinfo[fd];
67 unsigned char compress[4];
68
69 /*
70 * Check to see if the file is in compress mode
71 * 4 possibilities
72 * compressed flag in cellhd is negative (meaning pre 3.0 cell file)
73 * compression flag is first 3 bytes of cell file
74 * compression flag is 0 - not compressed
75 * compression flag is 1 - compressed using RLE (int) or zlib (FP)
76 * compression flag is 2 - compressed using zlib
77 */
78
79 if (fcb->cellhd.compressed < 0) {
80 if (read(fcb->data_fd, compress, 3) != 3 || compress[0] != 251 ||
81 compress[1] != 255 || compress[2] != 251)
82 fcb->cellhd.compressed = 0;
83 }
84
85 if (!fcb->cellhd.compressed)
86 return 1;
87
88 /* allocate space to hold the row address array */
89 fcb->row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
90
91 /* read the row address array */
92 return Rast__read_row_ptrs(fd);
93}
94
95static int read_row_ptrs(int nrows, int old, off_t *row_ptr, int fd)
96{
97 unsigned char nbytes;
98 unsigned char *buf, *b;
99 unsigned int n;
100 unsigned int row;
101
102 assert(nrows >= 0);
103
104 /*
105 * pre3.0 row addresses were written directly from the array of off_t's
106 * (this makes them machine dependent)
107 */
108
109 if (old) {
110 n = ((unsigned int)nrows + 1) * sizeof(off_t);
111 if (read(fd, row_ptr, n) != n)
112 return -1;
113 return 1;
114 }
115
116 /*
117 * 3.0 row address array is in a machine independent format
118 * (warning - the format will work even if the sizeof(off_t) is
119 * not the same from machine to machine, as long as the
120 * actual values do not exceed the capability of the off_t)
121 */
122
123 if (read(fd, &nbytes, 1) != 1)
124 return -1;
125 if (nbytes == 0)
126 return -1;
127
128 n = ((unsigned int)nrows + 1) * nbytes;
129 buf = G_malloc(n);
130 if (read(fd, buf, n) != n)
131 goto badread;
132
133 for (row = 0, b = buf; row <= (unsigned int)nrows; row++) {
134 off_t v = 0;
135
136 for (n = 0; n < nbytes; n++) {
137 unsigned char c = *b++;
138
139 if (nbytes > sizeof(off_t) && n < nbytes - sizeof(off_t) && c != 0)
140 goto badread;
141
142 v <<= 8;
143 v += c;
144 }
145
146 row_ptr[row] = v;
147 }
148
149 G_free(buf);
150
151 return 1;
152
153badread:
154 G_free(buf);
155 return -1;
156}
157
159{
160 struct fileinfo *fcb = &R__.fileinfo[fd];
161 int nrows = fcb->cellhd.rows;
162 int old = fcb->cellhd.compressed < 0;
163
164 if (read_row_ptrs(nrows, old, fcb->row_ptr, fcb->data_fd) < 0) {
165 G_warning(_("Fail of initial read of compressed file [%s in %s]"),
166 fcb->name, fcb->mapset);
167 return -1;
168 }
169
170 return 1;
171}
172
174{
175 struct fileinfo *fcb = &R__.fileinfo[fd];
176 int nrows = fcb->cellhd.rows;
177
178 if (read_row_ptrs(nrows, 0, fcb->null_row_ptr, null_fd) < 0) {
179 G_warning(_("Fail of initial read of compressed null file [%s in %s]"),
180 fcb->name, fcb->mapset);
181 return -1;
182 }
183
184 return 1;
185}
186
187static int write_row_ptrs(int nrows, off_t *row_ptr, int fd)
188{
189 int nbytes = sizeof(off_t);
190 unsigned char *buf, *b;
191 int len, row, result;
192
193 if (lseek(fd, 0L, SEEK_SET) == -1) {
194 int err = errno;
195 G_fatal_error(_("File read/write operation failed: %s (%d)"),
196 strerror(err), err);
197 }
198
199 len = (nrows + 1) * nbytes + 1;
200 b = buf = G_malloc(len);
201 *b++ = nbytes;
202
203 for (row = 0; row <= nrows; row++) {
204 off_t v = row_ptr[row];
205 int i;
206
207 for (i = nbytes - 1; i >= 0; i--) {
208 b[i] = v & 0xff;
209 v >>= 8;
210 }
211
212 b += nbytes;
213 }
214
215 result = (write(fd, buf, len) == len);
216 G_free(buf);
217
218 return result;
219}
220
222{
223 struct fileinfo *fcb = &R__.fileinfo[fd];
224 int nrows = fcb->cellhd.rows;
225
226 return write_row_ptrs(nrows, fcb->row_ptr, fcb->data_fd);
227}
228
230{
231 struct fileinfo *fcb = &R__.fileinfo[fd];
232 int nrows = fcb->cellhd.rows;
233
234 return write_row_ptrs(nrows, fcb->null_row_ptr, null_fd);
235}
AMI_err name(char **stream_name)
Definition ami_stream.h:426
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:147
#define G_calloc(m, n)
Definition defs/gis.h:140
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
#define G_malloc(n)
Definition defs/gis.h:139
#define _(str)
Definition glocale.h:10
#define assert(condition)
Definition lz4.c:291
double b
Definition r_raster.c:39
int Rast__write_null_row_ptrs(int fd, int null_fd)
int Rast__read_null_row_ptrs(int fd, int null_fd)
int Rast__check_format(int fd)
int Rast__write_row_ptrs(int fd)
int Rast__read_row_ptrs(int fd)
Definition R.h:82
struct fileinfo * fileinfo
Definition R.h:96
Definition R.h:48
off_t * row_ptr
Definition R.h:57
int null_fd
Definition R.h:64
int nbytes
Definition R.h:66
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
#define read
Definition unistd.h:5
#define write
Definition unistd.h:6