/src/gdal/frmts/pcraster/libcsf/mopen.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include <string.h> |
2 | | |
3 | | #include "csf.h" |
4 | | #include "csfimpl.h" |
5 | | |
6 | | |
7 | | static const char * const openModes[3] = { |
8 | | S_READ, |
9 | | S_WRITE, |
10 | | S_READ_WRITE |
11 | | }; |
12 | | |
13 | | /* Return the access mode of m |
14 | | * MopenPerm returns the permission. |
15 | | * Note that M_WRITE is deprecated |
16 | | */ |
17 | | enum MOPEN_PERM MopenPerm( |
18 | | const MAP *m) |
19 | 0 | { |
20 | 0 | return m->fileAccessMode; |
21 | 0 | } |
22 | | |
23 | | /* open an existing CSF file |
24 | | * Mopen opens a CSF file. It allocates space for |
25 | | * the MAP runtime-structure, reads the header file |
26 | | * and performs test to determine if it is a CSF file. |
27 | | * The MinMaxStatus is set to MM_KEEPTRACK if the min/max |
28 | | * header fields are not MV or MM_WRONGVALUE if one of them |
29 | | * contains a MV. |
30 | | * returns a pointer the MAP runtime structure if the file is |
31 | | * successfully opened as a CSF file, NULL if not. |
32 | | * |
33 | | * Merrno |
34 | | * NOCORE BADACCESMODE OPENFAILED NOT_CSF BAD_VERSION |
35 | | * |
36 | | * EXAMPLE |
37 | | * .so examples/testcsf.tr |
38 | | */ |
39 | | MAP *Mopen( |
40 | | const char *fileName, /* file name */ |
41 | | enum MOPEN_PERM mode) /* file permission */ |
42 | 0 | { |
43 | 0 | MAP *m; |
44 | 0 | UINT4 s; /* swap detection field */ |
45 | | |
46 | 0 | if (! CsfIsBootedCsfKernel()) |
47 | 0 | CsfBootCsfKernel(); |
48 | | |
49 | 0 | m = (MAP *)CSF_MALLOC(sizeof(MAP)); |
50 | | |
51 | 0 | if (m == NULL) |
52 | 0 | { |
53 | 0 | M_ERROR(NOCORE); |
54 | 0 | goto error_mapMalloc; |
55 | 0 | } |
56 | | |
57 | 0 | m->fileName = (char *)CSF_MALLOC(strlen(fileName)+1); |
58 | 0 | if (m->fileName == NULL) |
59 | 0 | { |
60 | 0 | M_ERROR(NOCORE); |
61 | 0 | goto error_fnameMalloc; |
62 | 0 | } |
63 | 0 | (void)strcpy(m->fileName,fileName); |
64 | | |
65 | | /* check file mode validation */ |
66 | 0 | if ( IS_BAD_ACCESS_MODE(mode)) |
67 | 0 | { |
68 | 0 | M_ERROR(BADACCESMODE); |
69 | 0 | goto error_notOpen; |
70 | 0 | } |
71 | 0 | m->fileAccessMode = mode; |
72 | | |
73 | | |
74 | | /* check if file can be opened or exists */ |
75 | 0 | m->fp = fopen(fileName, openModes[mode-1]); |
76 | 0 | if (m->fp == NULL) |
77 | 0 | { |
78 | 0 | M_ERROR(OPENFAILED); |
79 | 0 | goto error_notOpen; |
80 | 0 | } |
81 | | |
82 | | /* check if file could be C.S.F.-file |
83 | | * (at least 256 bytes long) |
84 | | * otherwise the signature comparison will |
85 | | * fail |
86 | | */ |
87 | | |
88 | 0 | (void)csf_fseek(m->fp,0, SEEK_END); |
89 | 0 | if (csf_ftell(m->fp) < ADDR_DATA) |
90 | 0 | { |
91 | 0 | M_ERROR(NOT_CSF); |
92 | 0 | goto error_open; |
93 | 0 | } |
94 | | |
95 | 0 | (void)csf_fseek(m->fp, 14+CSF_SIG_SPACE, SEEK_SET); |
96 | 0 | if (1 != fread((void *)&s, sizeof(UINT4),(size_t)1,m->fp)) |
97 | 0 | { |
98 | 0 | fprintf(stderr, "WARNING: Unable to read ORD_OK in CSF.\n"); |
99 | 0 | } |
100 | 0 | if (s != ORD_OK) { |
101 | 0 | if( s != ORD_SWAB ) |
102 | 0 | { |
103 | 0 | M_ERROR(NOT_CSF); |
104 | 0 | goto error_open; |
105 | 0 | } |
106 | 0 | m->write = CsfWriteSwapped; |
107 | 0 | m->read = CsfReadSwapped; |
108 | 0 | } |
109 | 0 | else { |
110 | | #ifdef DEBUG |
111 | | m->read = (CSF_READ_FUNC)CsfReadPlain; |
112 | | m->write = (CSF_READ_FUNC)CsfWritePlain; |
113 | | #else |
114 | 0 | m->read = (CSF_READ_FUNC)fread; |
115 | 0 | m->write = (CSF_READ_FUNC)fwrite; |
116 | 0 | #endif |
117 | 0 | } |
118 | | |
119 | 0 | (void)csf_fseek(m->fp, ADDR_MAIN_HEADER, SEEK_SET); |
120 | 0 | m->read((void *)&(m->main.signature), sizeof(char), CSF_SIG_SPACE,m->fp); |
121 | 0 | m->read((void *)&(m->main.version), sizeof(UINT2),(size_t)1,m->fp); |
122 | 0 | m->read((void *)&(m->main.gisFileId), sizeof(UINT4),(size_t)1,m->fp); |
123 | 0 | m->read((void *)&(m->main.projection),sizeof(UINT2),(size_t)1,m->fp); |
124 | 0 | m->read((void *)&(m->main.attrTable), sizeof(UINT4),(size_t)1,m->fp); |
125 | 0 | m->read((void *)&(m->main.mapType), sizeof(UINT2),(size_t)1,m->fp); |
126 | 0 | m->read((void *)&(m->main.byteOrder), sizeof(UINT4),(size_t)1,m->fp); |
127 | | /* 14+CSF_SIG_SPACE |
128 | | */ |
129 | | |
130 | 0 | (void)csf_fseek(m->fp, ADDR_SECOND_HEADER, SEEK_SET); |
131 | 0 | m->read((void *)&(m->raster.valueScale), sizeof(UINT2),(size_t)1,m->fp); |
132 | 0 | m->read((void *)&(m->raster.cellRepr), sizeof(UINT2),(size_t)1,m->fp); |
133 | |
|
134 | 0 | if (1 != fread((void *)&(m->raster.minVal), sizeof(CSF_VAR_TYPE),(size_t)1,m->fp)) |
135 | 0 | { |
136 | 0 | fprintf(stderr, "WARNING: Unable to read min val in CSF.\n"); |
137 | 0 | } |
138 | 0 | if (1 != fread((void *)&(m->raster.maxVal), sizeof(CSF_VAR_TYPE),(size_t)1,m->fp)) |
139 | 0 | { |
140 | 0 | fprintf(stderr, "WARNING: Unable to read max val in CSF.\n"); |
141 | 0 | } |
142 | 0 | if (s != ORD_OK) { |
143 | 0 | CsfSwap((void *)&(m->raster.minVal), CELLSIZE(m->raster.cellRepr),(size_t)1); |
144 | 0 | CsfSwap((void *)&(m->raster.maxVal), CELLSIZE(m->raster.cellRepr),(size_t)1); |
145 | 0 | } |
146 | |
|
147 | 0 | m->read((void *)&(m->raster.xUL), sizeof(REAL8),(size_t)1,m->fp); |
148 | 0 | m->read((void *)&(m->raster.yUL), sizeof(REAL8),(size_t)1,m->fp); |
149 | 0 | m->read((void *)&(m->raster.nrRows), sizeof(UINT4),(size_t)1,m->fp); |
150 | 0 | m->read((void *)&(m->raster.nrCols), sizeof(UINT4),(size_t)1,m->fp); |
151 | 0 | m->read((void *)&(m->raster.cellSize), sizeof(REAL8),(size_t)1,m->fp); |
152 | 0 | m->read((void *)&(m->raster.cellSizeDupl), sizeof(REAL8),(size_t)1,m->fp); |
153 | |
|
154 | 0 | m->read((void *)&(m->raster.angle), sizeof(REAL8),(size_t)1,m->fp); |
155 | | |
156 | | |
157 | | /* check signature C.S.F.file |
158 | | */ |
159 | 0 | if(strncmp(m->main.signature,CSF_SIG,CSF_SIZE_SIG)!=0) |
160 | 0 | { |
161 | 0 | M_ERROR(NOT_CSF); |
162 | 0 | goto error_open; |
163 | 0 | } |
164 | | /* should be read right |
165 | | */ |
166 | 0 | POSTCOND(m->main.byteOrder == ORD_OK); |
167 | | /* restore byteOrder C.S.F.file (Intel or Motorola) */ |
168 | 0 | m->main.byteOrder=s; |
169 | | |
170 | | /* check version C.S.F.file |
171 | | */ |
172 | 0 | if (m->main.version != CSF_VERSION_1 |
173 | 0 | && (m->main.version != CSF_VERSION_2)) |
174 | 0 | { |
175 | 0 | M_ERROR(BAD_VERSION); |
176 | 0 | goto error_open; |
177 | 0 | } |
178 | | |
179 | 0 | if (m->main.version == CSF_VERSION_1) |
180 | 0 | m->raster.angle = 0.0; |
181 | | |
182 | | /* validate value of cellRepr */ |
183 | 0 | switch(m->raster.cellRepr) |
184 | 0 | { |
185 | 0 | case CR_UINT1: |
186 | 0 | case CR_INT4: |
187 | 0 | case CR_REAL4: |
188 | 0 | case CR_REAL8: |
189 | 0 | case CR_INT1: |
190 | 0 | case CR_INT2: |
191 | 0 | case CR_UINT2: |
192 | 0 | case CR_UINT4: |
193 | 0 | case CR_UNDEFINED: |
194 | 0 | break; |
195 | | |
196 | 0 | default: |
197 | 0 | M_ERROR(BAD_CELLREPR); |
198 | 0 | goto error_open; |
199 | 0 | } |
200 | | |
201 | | /* validate value of valueScale */ |
202 | 0 | switch(m->raster.valueScale) |
203 | 0 | { |
204 | 0 | case VS_NOTDETERMINED: |
205 | 0 | case VS_CLASSIFIED: |
206 | 0 | case VS_CONTINUOUS: |
207 | 0 | case VS_BOOLEAN: |
208 | 0 | case VS_NOMINAL: |
209 | 0 | case VS_ORDINAL: |
210 | 0 | case VS_SCALAR: |
211 | 0 | case VS_DIRECTION: |
212 | 0 | case VS_LDD: |
213 | 0 | case VS_UNDEFINED: |
214 | 0 | break; |
215 | | |
216 | 0 | default: |
217 | 0 | M_ERROR(BAD_VALUESCALE); |
218 | 0 | goto error_open; |
219 | 0 | } |
220 | | |
221 | 0 | CsfFinishMapInit(m); |
222 | | |
223 | 0 | CsfRegisterMap(m); |
224 | | |
225 | | /* install cell value converters: (app2file,file2app) |
226 | | */ |
227 | 0 | m->app2file = CsfDummyConversion; |
228 | 0 | m->file2app = CsfDummyConversion; |
229 | 0 | m->appCR = m->raster.cellRepr; |
230 | | |
231 | 0 | if (IsMV(m,&(m->raster.minVal)) || |
232 | 0 | IsMV(m,&(m->raster.maxVal)) ) |
233 | 0 | m->minMaxStatus = MM_WRONGVALUE; |
234 | 0 | else |
235 | 0 | m->minMaxStatus = MM_KEEPTRACK; |
236 | | |
237 | 0 | return(m); |
238 | | |
239 | 0 | error_open: |
240 | 0 | PRECOND(m->fp != NULL); |
241 | 0 | (void)fclose(m->fp); |
242 | 0 | error_notOpen: |
243 | 0 | CSF_FREE(m->fileName); |
244 | 0 | error_fnameMalloc: |
245 | 0 | CSF_FREE(m); |
246 | 0 | error_mapMalloc: |
247 | 0 | return(NULL); |
248 | 0 | } |