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