1 /*============================================================================
2 MetaIO
3 Copyright 2000-2010 Insight Software Consortium
4
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
7
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 /**
13 * MetaUtils (.h and .cpp)
14 *
15 * Description:
16 * This file provides generic ascii file parsing capabilities.
17 * It assumes that the files consist of a set of fields
18 * Each field is list of variable = value pairs
19 *
20 * Features:
21 * There can be dependencies between fields, required fields,
22 * and optional fields.
23 * Undefined fields are skipped.
24 * Values must conform to expected types. There can be default
25 * values for fields.
26 *
27 * Author:
28 * Stephen R. Aylward
29 *
30 * Date:
31 * February 22, 2002
32 *
33 **/
34 #include "metaTypes.h"
35
36 #ifndef ITKMetaIO_METAUTILS_H
37 #define ITKMetaIO_METAUTILS_H
38
39 #ifdef _MSC_VER
40 #pragma warning( disable:4251 )
41 #pragma warning( disable:4511 )
42 #pragma warning( disable:4512 )
43 #pragma warning( disable:4284 )
44 #pragma warning( disable:4702 )
45 #pragma warning( disable:4786 )
46 #pragma warning( disable:4996 )
47 #endif
48
49 #include <vector>
50 #include <string>
51 #include <sstream>
52 #include <iostream>
53 //#include <iomanip>
54 #include <typeinfo>
55 #include <string.h>
56
57 #if (METAIO_USE_NAMESPACE)
58 namespace METAIO_NAMESPACE {
59 #endif
60
61 extern int META_DEBUG;
62
63 // Types used for storing the compression table
64 typedef struct MET_CompressionOffset
65 {
66 std::streamoff uncompressedOffset;
67 std::streamoff compressedOffset;
68 } MET_CompressionOffsetType;
69
70 typedef std::vector<MET_CompressionOffsetType> MET_CompressionOffsetListType;
71
72 typedef struct MET_CompressionTable
73 {
74 MET_CompressionOffsetListType offsetList;
75 z_stream* compressedStream;
76 char* buffer;
77 std::streamoff bufferSize;
78 } MET_CompressionTableType;
79
80 /////////////////////////////////////////////////////////
81 /////////////////////////////////////////////////////////
82 METAIO_EXPORT MET_FieldRecordType *
83 MET_GetFieldRecord(const char * _fieldName, std::vector<MET_FieldRecordType *> * _fields);
84
85 METAIO_EXPORT
86 int MET_GetFieldRecordNumber(const char * _fieldName, std::vector<MET_FieldRecordType *> * _fields);
87
88 METAIO_EXPORT
89 bool MET_SizeOfType(MET_ValueEnumType _type, int *_size);
90
91 /////////////////////////////////////////////////////////
92 // Byte Order
93 /////////////////////////////////////////////////////////
94 METAIO_EXPORT
95 bool MET_SystemByteOrderMSB(void);
96
97 inline
MET_ByteOrderSwapShort(unsigned short x)98 unsigned short MET_ByteOrderSwapShort(unsigned short x)
99 {
100 return (unsigned short)((unsigned short)(x<<8) | (unsigned short)(x>>8));
101 }
102
103 inline
MET_ByteOrderSwapLong(unsigned int x)104 unsigned int MET_ByteOrderSwapLong(unsigned int x)
105 {
106 return (((x<<24) & 0xff000000) |
107 ((x<<8) & 0x00ff0000) |
108 ((x>>8) & 0x0000ff00) |
109 ((x>>24) & 0x000000ff));
110 }
111
112 inline
MET_ByteOrderSwap2(void * x)113 void MET_ByteOrderSwap2(void* x)
114 {
115 char one_byte;
116 char *p = reinterpret_cast<char *>(x);
117
118 one_byte = p[0];
119 p[0] = p[1];
120 p[1] = one_byte;
121 }
122
123 inline
MET_ByteOrderSwap4(void * x)124 void MET_ByteOrderSwap4(void* x)
125 {
126 char one_byte;
127 char *p = reinterpret_cast<char *>(x);
128
129 one_byte = p[0];
130 p[0] = p[3];
131 p[3] = one_byte;
132
133 one_byte = p[1];
134 p[1] = p[2];
135 p[2] = one_byte;
136 }
137
138 inline
MET_ByteOrderSwap8(void * x)139 void MET_ByteOrderSwap8(void* x)
140 {
141 char one_byte;
142 char* p = reinterpret_cast<char*>(x);
143 one_byte = p[0];
144 p[0] = p[7];
145 p[7] = one_byte;
146
147 one_byte = p[1];
148 p[1] = p[6];
149 p[6] = one_byte;
150
151 one_byte = p[2];
152 p[2] = p[5];
153 p[5] = one_byte;
154
155 one_byte = p[3];
156 p[3] = p[4];
157 p[4] = one_byte;
158 }
159
160 /** Make sure that all the byte are read and written as LSB */
161 void MET_SwapByteIfSystemMSB(void* val, MET_ValueEnumType _type);
162
163
164 /////////////////////////////////////////////////////////
165 // STRINGS AND TYPES
166 /////////////////////////////////////////////////////////
167 METAIO_EXPORT
168 bool MET_StringToWordArray(const char *s, int *n, char ***val);
169
170 template <class T>
171 void MET_StringToVector( const std::string & s,
172 std::vector< T > & vec,
173 const char separator=',' )
174 {
175 vec.clear();
176
177 std::string::size_type prevPos = 0;
178 std::string::size_type pos = s.find( separator, prevPos );
179 T tVal;
180 while( pos != std::string::npos )
181 {
182 std::stringstream ss;
183 std::string tmpString = s.substr( prevPos, (pos-prevPos) );
184 ss << tmpString;
185 ss >> tVal;
186 vec.push_back( tVal );
187
188 prevPos = pos+1;
189 pos = s.find( separator, prevPos );
190 }
191 std::stringstream ss;
192 std::string tmpString = s.substr( prevPos, ( s.size() - prevPos ) );
193 ss << tmpString;
194 ss >> tVal;
195 vec.push_back( tVal );
196 }
197
198 METAIO_EXPORT
199 bool MET_StringToType(const char *_str, MET_ValueEnumType *_type);
200
201 METAIO_EXPORT
202 bool MET_TypeToString(MET_ValueEnumType _type, char *_str);
203
204 METAIO_EXPORT
205 bool MET_StringToInterpolationType(const char * _str, MET_InterpolationEnumType * _type);
206
207 METAIO_EXPORT
208 bool MET_InterpolationTypeToString(MET_InterpolationEnumType _type, char * _str);
209
210 inline
MET_GetPixelType(const std::type_info & ptype)211 MET_ValueEnumType MET_GetPixelType(const std::type_info & ptype)
212 {
213 if( ptype == typeid(MET_UCHAR_TYPE) )
214 {
215 return MET_UCHAR;
216 }
217 else if( ptype == typeid(MET_CHAR_TYPE) )
218 {
219 return MET_CHAR;
220 }
221 else if( ptype == typeid(MET_USHORT_TYPE))
222 {
223 return MET_USHORT;
224 }
225 else if( ptype == typeid(MET_SHORT_TYPE) )
226 {
227 return MET_SHORT;
228 }
229 else if( ptype == typeid(MET_UINT_TYPE) )
230 {
231 return MET_UINT;
232 }
233 else if( ptype == typeid(MET_INT_TYPE) )
234 {
235 return MET_INT;
236 }
237 else if( ptype == typeid(MET_ULONG_TYPE))
238 {
239 return MET_ULONG;
240 }
241 else if( ptype == typeid(MET_LONG_TYPE) )
242 {
243 return MET_LONG;
244 }
245 else if( ptype == typeid(MET_ULONG_LONG_TYPE) )
246 {
247 return MET_ULONG_LONG;
248 }
249 else if( ptype == typeid(MET_LONG_LONG_TYPE) )
250 {
251 return MET_LONG_LONG;
252 }
253 else if( ptype == typeid(MET_FLOAT_TYPE) )
254 {
255 return MET_FLOAT;
256 }
257 else if( ptype == typeid(MET_DOUBLE_TYPE) )
258 {
259 return MET_DOUBLE;
260 }
261 else
262 {
263 std::cerr << "MET_GetPixelType: Couldn't convert pixel type : "
264 << ptype.name() << std::endl;
265 return MET_NONE;
266 }
267 }
268
269 inline
MET_GetValueEnumType(const std::type_info & ptype)270 MET_ValueEnumType MET_GetValueEnumType(const std::type_info & ptype)
271 {
272 return MET_GetPixelType( ptype );
273 }
274
275 inline
MET_StringStripEnd(MET_ASCII_CHAR_TYPE * str)276 void MET_StringStripEnd(MET_ASCII_CHAR_TYPE * str)
277 {
278 // note the post-decrement in the condition
279 for(size_t j = strlen(str); j-- > 0;)
280 {
281 if(isprint(str[j]) && !isspace(str[j]))
282 {
283 break;
284 }
285 str[j] = '\0';
286 }
287 }
288
289
290 /////////////////////////////////////////////////////////
291 // VALUES
292 /////////////////////////////////////////////////////////
293 METAIO_EXPORT
294 bool MET_ValueToDouble(MET_ValueEnumType _pType,
295 const void *_data,
296 std::streamoff _index,
297 double *_value);
298
299 METAIO_EXPORT
300 bool MET_DoubleToValue(double _value,
301 MET_ValueEnumType _type,
302 void *_data,
303 std::streamoff _index);
304
305 METAIO_EXPORT
306 bool MET_ValueToValue(MET_ValueEnumType _fromType,
307 const void *_fromData,
308 std::streamoff _index,
309 MET_ValueEnumType _toType,
310 void *_toData,
311 double _fromMin=0, double _fromMax=0,
312 double _toMin=0, double _toMax=0);
313
314 METAIO_EXPORT
315 unsigned char * MET_PerformCompression(const unsigned char * source,
316 std::streamoff sourceSize,
317 std::streamoff * compressedDataSize,
318 int compressionLevel);
319
320 METAIO_EXPORT
321 bool MET_PerformUncompression(const unsigned char * sourceCompressed,
322 std::streamoff sourceCompressedSize,
323 unsigned char * uncompressedData,
324 std::streamoff uncompressedDataSize);
325
326 // Uncompress a stream given an uncompressedSeekPosition
327 METAIO_EXPORT
328 std::streamoff MET_UncompressStream(std::ifstream * stream,
329 std::streamoff uncompressedSeekPosition,
330 unsigned char * uncompressedData,
331 std::streamoff uncompressedDataSize,
332 std::streamoff compressedDataSize,
333 MET_CompressionTableType * compressionTable);
334
335
336 /////////////////////////////////////////////////////////
337 // FILES NAMES
338 /////////////////////////////////////////////////////////
339 METAIO_EXPORT
340 bool MET_GetFilePath(const std::string& _fName, std::string& _fPath);
341
342 METAIO_EXPORT
343 bool MET_GetFileSuffixPtr(const std::string& _fName, int *i);
344
345 METAIO_EXPORT
346 bool MET_SetFileSuffix(std::string& _fName, const std::string& _suf);
347
348 /////////////////////////////////////////////////////////
349 /////////////////////////////////////////////////////////
350 METAIO_EXPORT
351 bool MET_InitWriteField(MET_FieldRecordType * _mf,
352 const char *_name,
353 MET_ValueEnumType _type,
354 double _v=0);
355
356 template <class T>
MET_InitWriteField(MET_FieldRecordType * _mf,const char * _name,MET_ValueEnumType _type,size_t _length,T * _v)357 bool MET_InitWriteField(MET_FieldRecordType * _mf,
358 const char *_name,
359 MET_ValueEnumType _type,
360 size_t _length,
361 T *_v)
362 {
363 strncpy(_mf->name, _name,254);
364 _mf->name[254] = '\0';
365 _mf->type = _type;
366 _mf->defined = true;
367 _mf->length = static_cast<int>(_length);
368 _mf->dependsOn = -1;
369 _mf->required = false;
370 _mf->terminateRead = false;
371 if(_type == MET_FLOAT_MATRIX)
372 {
373 size_t i;
374 for(i=0; i < MET_MAX_NUMBER_OF_FIELD_VALUES && i < _length*_length; i++)
375 {
376 _mf->value[i] = (double)(_v[i]);
377 }
378 }
379 else if(_type != MET_STRING)
380 {
381 size_t i;
382 for(i=0; i < MET_MAX_NUMBER_OF_FIELD_VALUES && i < _length; i++)
383 {
384 _mf->value[i] = (double)(_v[i]);
385 }
386 }
387 else
388 {
389 strncpy((char *)(_mf->value), (const char *)_v,
390 (sizeof(_mf->value)-1));
391 ((char *)(_mf->value))[(sizeof(_mf->value)-1)] = '\0';
392 }
393 return true;
394 }
395
396 /////////////////////////////////////////////////////////
397 /////////////////////////////////////////////////////////
398 METAIO_EXPORT
399 bool MET_Write(std::ostream &fp,
400 std::vector<MET_FieldRecordType *> * fields,
401 char _sepChar='=');
402
403 METAIO_EXPORT
404 bool MET_WriteFieldToFile(std::ostream &_fp, const char *_fieldName,
405 MET_ValueEnumType _pType, size_t _n, const void *_v);
406
407 METAIO_EXPORT
408 bool MET_WriteFieldToFile(std::ostream &_fp, const char *_fieldName,
409 MET_ValueEnumType _pType, double _v);
410
411
412 /////////////////////////////////////////////////////////
413 /////////////////////////////////////////////////////////
414 METAIO_EXPORT
415 bool MET_InitReadField(MET_FieldRecordType * _mf,
416 const char *_name,
417 MET_ValueEnumType _type,
418 bool _required=true,
419 int _dependsOn=-1,
420 size_t _length=0);
421
422 /////////////////////////////////////////////////////////
423 /////////////////////////////////////////////////////////
424 METAIO_EXPORT
425 bool MET_Read(std::istream &fp,
426 std::vector<MET_FieldRecordType *> * fields,
427 char _sepChar='=', bool oneLine=false,
428 bool display_warnings=true,
429 std::vector<MET_FieldRecordType *> * newFields=nullptr);
430
431
432 /////////////////////////////////////////////////////////
433 /////////////////////////////////////////////////////////
434 METAIO_EXPORT
435 std::string MET_ReadForm(std::istream & _fp);
436
437 METAIO_EXPORT
438 std::string MET_ReadType(std::istream & _fp);
439
440 METAIO_EXPORT
441 char * MET_ReadSubType(std::istream & _fp);
442
443 #if (METAIO_USE_NAMESPACE)
444 };
445 #endif
446
447
448 #endif
449