Coverage Report

Created: 2025-06-09 07:07

/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
}