~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to lib/gis/format.c

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <grass/gis.h>
2
 
#include <grass/glocale.h>
3
 
#include <unistd.h>
4
 
#include <stdlib.h>
5
 
 
6
 
#include <grass/config.h>
7
 
 
8
 
#ifdef HAVE_UNISTD_H
9
 
#include <unistd.h>
10
 
#endif
11
 
 
12
 
#include "G.h"
13
 
 
14
 
/*!
15
 
 
16
 
   <h3>GRASS Raster Format</h3>
17
 
 
18
 
   Small example to illustrate the raster format:
19
 
 
20
 
   A file may contain the following 3x3 floating point matrix:
21
 
   \verbatim
22
 
   10.000 20.000 30.000
23
 
   20.000 40.000 50.000
24
 
   30.000 50.000 60.000
25
 
   \endverbatim
26
 
 
27
 
   The header is a single byte, equal to sizeof(off_t) (typically 4 on a
28
 
   32-bit platform, 8 on a 64-bit platform). Then, NROWS+1 offsets are
29
 
   written as off_t's (i.e. 4 or 8 bytes, depending upon platform) in
30
 
   big-endian (Motorola) byte order.
31
 
   <P>
32
 
   Thus, above example is actually interpreted as:
33
 
   \verbatim
34
 
   4               sizeof(off_t)
35
 
   0 0 0 17        offset of row 0
36
 
   0 0 0 36        offset of row 1
37
 
   0 0 0 55        offset of row 2
38
 
   0 0 0 74        offset of end of data
39
 
   \endverbatim
40
 
 
41
 
   See G__write_row_ptrs() below for the code which writes this data. 
42
 
   However, note that the row offsets are initially zero; 
43
 
   they get overwritten later (if you are writing compressed data,
44
 
   you don't know how much space it will require until you've compressed
45
 
   it).
46
 
 
47
 
   As for the format of the actual row data, see put_fp_data() in
48
 
   src/libes/gis/put_row.c and RFC 1014 (the XDR specification):
49
 
   http://www.faqs.org/rfcs/rfc1014.html
50
 
 
51
 
 */
52
 
 
53
 
/**********************************************************************
54
 
 *
55
 
 *   G__check_format(int fd)
56
 
 *
57
 
 *   Check to see if map with file descriptor "fd" is in compressed
58
 
 *   format.   If it is, the offset table at the beginning of the 
59
 
 *   file (which gives seek addresses into the file where code for
60
 
 *   each row is found) is read into the File Control Buffer (FCB).
61
 
 *   The compressed flag in the FCB is appropriately set.
62
 
 *
63
 
 *   returns:    1 if row pointers were read successfully, -1 otherwise
64
 
 **********************************************************************/
65
 
 
66
 
int G__check_format(int fd)
67
 
{
68
 
    struct fileinfo *fcb = &G__.fileinfo[fd];
69
 
    unsigned char compress[4];
70
 
 
71
 
    /*
72
 
     * Check to see if the file is in compress mode
73
 
     * 4 possibilites
74
 
     *   compressed flag in cellhd is negative (meaning pre 3.0 cell file)
75
 
     *       compression flag is first 3 bytes of cell file
76
 
     *   compression flag is 0 - not compressed
77
 
     *   compression flag is 1 - compressed using RLE (int) or zlib (FP)
78
 
     *   compression flag is 2 - compressed using zlib
79
 
     */
80
 
 
81
 
    if (fcb->cellhd.compressed < 0) {
82
 
        if (read(fd, compress, 3) != 3
83
 
            || compress[0] != 251 || compress[1] != 255 || compress[2] != 251)
84
 
            fcb->cellhd.compressed = 0;
85
 
    }
86
 
 
87
 
    if (!fcb->cellhd.compressed)
88
 
        return fd;
89
 
 
90
 
    /* allocate space to hold the row address array */
91
 
    fcb->row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
92
 
 
93
 
    /* read the row address array */
94
 
    return G__read_row_ptrs(fd);
95
 
}
96
 
 
97
 
int G__read_row_ptrs(int fd)
98
 
{
99
 
    struct fileinfo *fcb = &G__.fileinfo[fd];
100
 
    int nrows = fcb->cellhd.rows;
101
 
    unsigned char nbytes;
102
 
    unsigned char *buf, *b;
103
 
    int n;
104
 
    int row;
105
 
 
106
 
    /*
107
 
     * pre3.0 row addresses were written directly from the array of off_t's
108
 
     * (this makes them machine dependent)
109
 
     */
110
 
 
111
 
    if (fcb->cellhd.compressed < 0) {
112
 
        n = (nrows + 1) * sizeof(off_t);
113
 
        if (read(fd, fcb->row_ptr, n) != n)
114
 
            goto badread;
115
 
        return 1;
116
 
    }
117
 
 
118
 
    /*
119
 
     * 3.0 row address array is in a machine independent format
120
 
     * (warning - the format will work even if the sizeof(off_t) is
121
 
     *  not the same from machine to machine, as long as the
122
 
     *  actual values do not exceed the capability of the off_t)
123
 
     */
124
 
 
125
 
    if (read(fd, &nbytes, 1) != 1)
126
 
        goto badread;
127
 
    if (nbytes == 0)
128
 
        goto badread;
129
 
 
130
 
    n = (nrows + 1) * nbytes;
131
 
    buf = G_malloc(n);
132
 
    if (read(fd, buf, n) != n)
133
 
        goto badread;
134
 
 
135
 
    for (row = 0, b = buf; row <= nrows; row++) {
136
 
        off_t v = 0;
137
 
 
138
 
        for (n = 0; n < (int)nbytes; n++) {
139
 
            unsigned char c = *b++;
140
 
 
141
 
            if (nbytes > sizeof(off_t) && n < nbytes - sizeof(off_t) &&
142
 
                c != 0)
143
 
                goto badread;
144
 
 
145
 
            v <<= 8;
146
 
            v += c;
147
 
        }
148
 
 
149
 
        fcb->row_ptr[row] = v;
150
 
    }
151
 
 
152
 
    G_free(buf);
153
 
 
154
 
    return 1;
155
 
 
156
 
  badread:
157
 
    G_warning(_("Fail of initial read of compressed file [%s in %s]"),
158
 
              fcb->name, fcb->mapset);
159
 
    return -1;
160
 
}
161
 
 
162
 
int G__write_row_ptrs(int fd)
163
 
{
164
 
    struct fileinfo *fcb = &G__.fileinfo[fd];
165
 
    int nrows = fcb->cellhd.rows;
166
 
    int nbytes = sizeof(off_t);
167
 
    unsigned char *buf, *b;
168
 
    int len, row, result;
169
 
 
170
 
    lseek(fd, 0L, SEEK_SET);
171
 
 
172
 
    len = (nrows + 1) * nbytes + 1;
173
 
    b = buf = G_malloc(len);
174
 
    *b++ = nbytes;
175
 
 
176
 
    for (row = 0; row <= nrows; row++) {
177
 
        off_t v = fcb->row_ptr[row];
178
 
        int i;
179
 
 
180
 
        for (i = nbytes - 1; i >= 0; i--) {
181
 
            b[i] = v & 0xff;
182
 
            v >>= 8;
183
 
        }
184
 
 
185
 
        b += nbytes;
186
 
    }
187
 
 
188
 
    result = (write(fd, buf, len) == len);
189
 
    G_free(buf);
190
 
 
191
 
    return result;
192
 
}