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
Mclose(MAP * m)16  */
17 enum MOPEN_PERM MopenPerm(
18 	const MAP *m)
19 {
20  return m->fileAccessMode;
21 }
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 {
43  MAP *m;
44  UINT4 s; /* swap detection field */
45 
46  if (! CsfIsBootedCsfKernel())
47  	CsfBootCsfKernel();
48 
49  m = (MAP *)CSF_MALLOC(sizeof(MAP));
50 
51  if (m == NULL)
52  {
53  	M_ERROR(NOCORE);
54  	goto error_mapMalloc;
55  }
56 
57  m->fileName = (char *)CSF_MALLOC(strlen(fileName)+1);
58  if (m->fileName == NULL)
59  {
60  	M_ERROR(NOCORE);
61  	goto error_fnameMalloc;
62  }
63  (void)strcpy(m->fileName,fileName);
64 
65  /* check file mode validation */
66  if ( IS_BAD_ACCESS_MODE(mode))
67  {
68  	M_ERROR(BADACCESMODE);
69  	goto error_notOpen;
70  }
71  m->fileAccessMode = mode;
72 
73 
74  /*  check if file can be opened or exists */
75  m->fp = fopen(fileName, openModes[mode-1]);
76  if (m->fp == NULL)
77  {
78  	M_ERROR(OPENFAILED);
79  	goto error_notOpen;
80  }
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  (void)csf_fseek(m->fp,0, SEEK_END);
89  if (csf_ftell(m->fp) < ADDR_DATA)
90  {
91  	M_ERROR(NOT_CSF);
92  	goto error_open;
93  }
94 
95  (void)csf_fseek(m->fp, 14+CSF_SIG_SPACE, SEEK_SET);
96  if (1 != fread((void *)&s, sizeof(UINT4),(size_t)1,m->fp))
97  {
98      fprintf(stderr, "WARNING: Unable to read ORD_OK in CSF.\n");
99  }
100  if (s != ORD_OK) {
101     if( s != ORD_SWAB )
102     {
103         M_ERROR(NOT_CSF);
104         goto error_open;
105     }
106 	m->write = CsfWriteSwapped;
107 	m->read  = CsfReadSwapped;
108  }
109  else {
110 #ifdef DEBUG
111 	m->read  = (CSF_READ_FUNC)CsfReadPlain;
112 	m->write = (CSF_READ_FUNC)CsfWritePlain;
113 #else
114 	m->read  = (CSF_READ_FUNC)fread;
115 	m->write = (CSF_READ_FUNC)fwrite;
116 #endif
117  }
118 
119  (void)csf_fseek(m->fp, ADDR_MAIN_HEADER, SEEK_SET);
120  m->read((void *)&(m->main.signature), sizeof(char), CSF_SIG_SPACE,m->fp);
121  m->read((void *)&(m->main.version),   sizeof(UINT2),(size_t)1,m->fp);
122  m->read((void *)&(m->main.gisFileId), sizeof(UINT4),(size_t)1,m->fp);
123  m->read((void *)&(m->main.projection),sizeof(UINT2),(size_t)1,m->fp);
124  m->read((void *)&(m->main.attrTable), sizeof(UINT4),(size_t)1,m->fp);
125  m->read((void *)&(m->main.mapType),  sizeof(UINT2),(size_t)1,m->fp);
126  m->read((void *)&(m->main.byteOrder), sizeof(UINT4),(size_t)1,m->fp);
127  /*                                             14+CSF_SIG_SPACE
128   */
129 
130  (void)csf_fseek(m->fp, ADDR_SECOND_HEADER, SEEK_SET);
131  m->read((void *)&(m->raster.valueScale), sizeof(UINT2),(size_t)1,m->fp);
132  m->read((void *)&(m->raster.cellRepr), sizeof(UINT2),(size_t)1,m->fp);
133 
134  if (1 != fread((void *)&(m->raster.minVal), sizeof(CSF_VAR_TYPE),(size_t)1,m->fp))
135  {
136      fprintf(stderr, "WARNING: Unable to read min val in CSF.\n");
137  }
138  if (1 != fread((void *)&(m->raster.maxVal), sizeof(CSF_VAR_TYPE),(size_t)1,m->fp))
139  {
140      fprintf(stderr, "WARNING: Unable to read max val in CSF.\n");
141  }
142  if (s != ORD_OK) {
143   CsfSwap((void *)&(m->raster.minVal), CELLSIZE(m->raster.cellRepr),(size_t)1);
144   CsfSwap((void *)&(m->raster.maxVal), CELLSIZE(m->raster.cellRepr),(size_t)1);
145  }
146 
147  m->read((void *)&(m->raster.xUL), sizeof(REAL8),(size_t)1,m->fp);
148  m->read((void *)&(m->raster.yUL), sizeof(REAL8),(size_t)1,m->fp);
149  m->read((void *)&(m->raster.nrRows), sizeof(UINT4),(size_t)1,m->fp);
150  m->read((void *)&(m->raster.nrCols), sizeof(UINT4),(size_t)1,m->fp);
151  m->read((void *)&(m->raster.cellSize), sizeof(REAL8),(size_t)1,m->fp);
152  m->read((void *)&(m->raster.cellSizeDupl), sizeof(REAL8),(size_t)1,m->fp);
153 
154  m->read((void *)&(m->raster.angle), sizeof(REAL8),(size_t)1,m->fp);
155 
156 
157  /*  check signature C.S.F.file
158   */
159  if(strncmp(m->main.signature,CSF_SIG,CSF_SIZE_SIG)!=0)
160  {
161  	M_ERROR(NOT_CSF);
162  	goto error_open;
163  }
164  /* should be read right
165   */
166  POSTCOND(m->main.byteOrder == ORD_OK);
167  /*  restore byteOrder C.S.F.file (Intel or Motorola)  */
168  m->main.byteOrder=s;
169 
170  /*  check version C.S.F.file
171   */
172  if (m->main.version != CSF_VERSION_1
173     && (m->main.version != CSF_VERSION_2))
174  {
175  	M_ERROR(BAD_VERSION);
176  	goto error_open;
177  }
178 
179  if (m->main.version == CSF_VERSION_1)
180  	m->raster.angle = 0.0;
181 
182  /* validate value of cellRepr */
183  switch(m->raster.cellRepr)
184  {
185      case CR_UINT1:
186      case CR_INT4:
187      case CR_REAL4:
188      case CR_REAL8:
189      case CR_INT1:
190      case CR_INT2:
191      case CR_UINT2:
192      case CR_UINT4:
193      case CR_UNDEFINED:
194          break;
195 
196      default:
197          M_ERROR(BAD_CELLREPR);
198          goto error_open;
199  }
200 
201  /* validate value of valueScale */
202  switch(m->raster.valueScale)
203  {
204      case VS_NOTDETERMINED:
205      case VS_CLASSIFIED:
206      case VS_CONTINUOUS:
207      case VS_BOOLEAN:
208      case VS_NOMINAL:
209      case VS_ORDINAL:
210      case VS_SCALAR:
211      case VS_DIRECTION:
212      case VS_LDD:
213      case VS_UNDEFINED:
214          break;
215 
216      default:
217          M_ERROR(BAD_VALUESCALE);
218          goto error_open;
219  }
220 
221  CsfFinishMapInit(m);
222 
223  CsfRegisterMap(m);
224 
225  /* install cell value converters: (app2file,file2app)
226   */
227  m->app2file = CsfDummyConversion;
228  m->file2app = CsfDummyConversion;
229  m->appCR    = m->raster.cellRepr;
230 
231  if (IsMV(m,&(m->raster.minVal)) ||
232      IsMV(m,&(m->raster.maxVal))   )
233  	m->minMaxStatus = MM_WRONGVALUE;
234  else
235  	m->minMaxStatus = MM_KEEPTRACK;
236 
237  return(m);
238 
239  error_open:
240  PRECOND(m->fp != NULL);
241  (void)fclose(m->fp);
242  error_notOpen:
243  CSF_FREE(m->fileName);
244  error_fnameMalloc:
245  CSF_FREE(m);
246 error_mapMalloc:
247 	 return(NULL);
248 }
249