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 <cstring>
56
57 # if (METAIO_USE_NAMESPACE)
58 namespace METAIO_NAMESPACE
59 {
60 # endif
61
62 extern bool META_DEBUG;
63
64 # define META_DEBUG_PRINT(content) \
65 if (META_DEBUG) \
66 { \
67 std::cout << content << std::endl; \
68 } \
69 static_assert(true, "Compiled away assert that syntactically require semicolon at end of macro.")
70
71 // Types used for storing the compression table
72 typedef struct MET_CompressionOffset
73 {
74 std::streamoff uncompressedOffset;
75 std::streamoff compressedOffset;
76 } MET_CompressionOffsetType;
77
78 typedef std::vector<MET_CompressionOffsetType> MET_CompressionOffsetListType;
79
80 typedef struct MET_CompressionTable
81 {
82 MET_CompressionOffsetListType offsetList;
83 z_stream * compressedStream;
84 char * buffer;
85 std::streamoff bufferSize;
86 } MET_CompressionTableType;
87
88 METAIO_EXPORT MET_FieldRecordType *
89 MET_GetFieldRecord(const char * _fieldName, std::vector<MET_FieldRecordType *> * _fields);
90
91 METAIO_EXPORT
92 int
93 MET_GetFieldRecordNumber(const char * _fieldName, std::vector<MET_FieldRecordType *> * _fields);
94
95 METAIO_EXPORT
96 bool
97 MET_SizeOfType(MET_ValueEnumType _vType, int * s);
98
99 // Byte Order
100 METAIO_EXPORT
101 bool
102 MET_SystemByteOrderMSB();
103
104 inline unsigned short
MET_ByteOrderSwapShort(unsigned short x)105 MET_ByteOrderSwapShort(unsigned short x)
106 {
107 return x << 8 | x >> 8;
108 }
109
110 inline unsigned int
MET_ByteOrderSwapLong(unsigned int x)111 MET_ByteOrderSwapLong(unsigned int x)
112 {
113 return (((x << 24) & 0xff000000) | ((x << 8) & 0x00ff0000) | ((x >> 8) & 0x0000ff00) | ((x >> 24) & 0x000000ff));
114 }
115
116 inline void
MET_ByteOrderSwap2(void * x)117 MET_ByteOrderSwap2(void * x)
118 {
119 char one_byte;
120 char * p = reinterpret_cast<char *>(x);
121
122 one_byte = p[0];
123 p[0] = p[1];
124 p[1] = one_byte;
125 }
126
127 inline void
MET_ByteOrderSwap4(void * x)128 MET_ByteOrderSwap4(void * x)
129 {
130 char one_byte;
131 char * p = reinterpret_cast<char *>(x);
132
133 one_byte = p[0];
134 p[0] = p[3];
135 p[3] = one_byte;
136
137 one_byte = p[1];
138 p[1] = p[2];
139 p[2] = one_byte;
140 }
141
142 inline void
MET_ByteOrderSwap8(void * x)143 MET_ByteOrderSwap8(void * x)
144 {
145 char one_byte;
146 char * p = reinterpret_cast<char *>(x);
147 one_byte = p[0];
148 p[0] = p[7];
149 p[7] = one_byte;
150
151 one_byte = p[1];
152 p[1] = p[6];
153 p[6] = one_byte;
154
155 one_byte = p[2];
156 p[2] = p[5];
157 p[5] = one_byte;
158
159 one_byte = p[3];
160 p[3] = p[4];
161 p[4] = one_byte;
162 }
163
164 /** Make sure that all the byte are read and written as LSB */
165 void
166 MET_SwapByteIfSystemMSB(void * val, MET_ValueEnumType _type);
167
168
169 // STRINGS AND TYPES
170 METAIO_EXPORT
171 bool
172 MET_StringToWordArray(const char * s, int * n, char *** val);
173
174 template <class T>
175 void
176 MET_StringToVector(const std::string & s, std::vector<T> & vec, const char separator = ',')
177 {
178 vec.clear();
179
180 std::string::size_type prevPos = 0;
181 std::string::size_type pos = s.find(separator, prevPos);
182 T tVal;
183 while (pos != std::string::npos)
184 {
185 std::stringstream ss;
186 std::string tmpString = s.substr(prevPos, (pos - prevPos));
187 ss << tmpString;
188 ss >> tVal;
189 vec.push_back(tVal);
190
191 prevPos = pos + 1;
192 pos = s.find(separator, prevPos);
193 }
194 std::stringstream ss;
195 std::string tmpString = s.substr(prevPos, (s.size() - prevPos));
196 ss << tmpString;
197 ss >> tVal;
198 vec.push_back(tVal);
199 }
200
201 METAIO_EXPORT
202 bool
203 MET_StringToType(const char * _s, MET_ValueEnumType * _vType);
204
205 METAIO_EXPORT
206 bool
207 MET_TypeToString(MET_ValueEnumType _vType, char * _s);
208
209 METAIO_EXPORT
210 bool
211 MET_StringToInterpolationType(const char * _str, MET_InterpolationEnumType * _type);
212
213 METAIO_EXPORT
214 bool
215 MET_InterpolationTypeToString(MET_InterpolationEnumType _type, char * _str);
216
217 inline MET_ValueEnumType
MET_GetPixelType(const std::type_info & ptype)218 MET_GetPixelType(const std::type_info & ptype)
219 {
220 if (ptype == typeid(MET_UCHAR_TYPE))
221 {
222 return MET_UCHAR;
223 }
224 else if (ptype == typeid(MET_CHAR_TYPE))
225 {
226 return MET_CHAR;
227 }
228 else if (ptype == typeid(MET_USHORT_TYPE))
229 {
230 return MET_USHORT;
231 }
232 else if (ptype == typeid(MET_SHORT_TYPE))
233 {
234 return MET_SHORT;
235 }
236 else if (ptype == typeid(MET_UINT_TYPE))
237 {
238 return MET_UINT;
239 }
240 else if (ptype == typeid(MET_INT_TYPE))
241 {
242 return MET_INT;
243 }
244 else if (ptype == typeid(MET_ULONG_TYPE))
245 {
246 return MET_ULONG;
247 }
248 else if (ptype == typeid(MET_LONG_TYPE))
249 {
250 return MET_LONG;
251 }
252 else if (ptype == typeid(MET_ULONG_LONG_TYPE))
253 {
254 return MET_ULONG_LONG;
255 }
256 else if (ptype == typeid(MET_LONG_LONG_TYPE))
257 {
258 return MET_LONG_LONG;
259 }
260 else if (ptype == typeid(MET_FLOAT_TYPE))
261 {
262 return MET_FLOAT;
263 }
264 else if (ptype == typeid(MET_DOUBLE_TYPE))
265 {
266 return MET_DOUBLE;
267 }
268 else
269 {
270 std::cerr << "MET_GetPixelType: Couldn't convert pixel type : " << ptype.name() << std::endl;
271 return MET_NONE;
272 }
273 }
274
275 inline MET_ValueEnumType
MET_GetValueEnumType(const std::type_info & ptype)276 MET_GetValueEnumType(const std::type_info & ptype)
277 {
278 return MET_GetPixelType(ptype);
279 }
280
281 inline void
MET_StringStripEnd(MET_ASCII_CHAR_TYPE * str)282 MET_StringStripEnd(MET_ASCII_CHAR_TYPE * str)
283 {
284 // note the post-decrement in the condition
285 for (size_t j = strlen(str); j-- > 0;)
286 {
287 if (isprint(str[j]) && !isspace(str[j]))
288 {
289 break;
290 }
291 str[j] = '\0';
292 }
293 }
294
295
296 // VALUES
297 METAIO_EXPORT
298 bool
299 MET_ValueToDouble(MET_ValueEnumType _type, const void * _data, std::streamoff _index, double * _value);
300
301 METAIO_EXPORT
302 bool
303 MET_DoubleToValue(double _value, MET_ValueEnumType _type, void * _data, std::streamoff _index);
304
305 METAIO_EXPORT
306 bool
307 MET_ValueToValue(MET_ValueEnumType _fromType,
308 const void * _fromData,
309 std::streamoff _index,
310 MET_ValueEnumType _toType,
311 void * _toData,
312 double _fromMin = 0,
313 double _fromMax = 0,
314 double _toMin = 0,
315 double _toMax = 0);
316
317 METAIO_EXPORT
318 unsigned char *
319 MET_PerformCompression(const unsigned char * source,
320 std::streamoff sourceSize,
321 std::streamoff * compressedDataSize,
322 int compressionLevel);
323
324 METAIO_EXPORT
325 bool
326 MET_PerformUncompression(const unsigned char * sourceCompressed,
327 std::streamoff sourceCompressedSize,
328 unsigned char * uncompressedData,
329 std::streamoff uncompressedDataSize);
330
331 // Uncompress a stream given an uncompressedSeekPosition
332 METAIO_EXPORT
333 std::streamoff
334 MET_UncompressStream(std::ifstream * stream,
335 std::streamoff uncompressedSeekPosition,
336 unsigned char * uncompressedData,
337 std::streamoff uncompressedDataSize,
338 std::streamoff compressedDataSize,
339 MET_CompressionTableType * compressionTable);
340
341
342 // FILES NAMES
343 METAIO_EXPORT
344 bool
345 MET_GetFilePath(const std::string & _fName, std::string & _fPath);
346
347 METAIO_EXPORT
348 bool
349 MET_GetFileSuffixPtr(const std::string & _fName, int * i);
350
351 METAIO_EXPORT
352 bool
353 MET_SetFileSuffix(std::string & _fName, const std::string & _suf);
354
355 METAIO_EXPORT
356 bool
357 MET_InitWriteField(MET_FieldRecordType * _mf, const char * _name, MET_ValueEnumType _type, double _v = 0);
358
359 template <class T>
360 bool
MET_InitWriteField(MET_FieldRecordType * _mf,const char * _name,MET_ValueEnumType _type,size_t _length,T * _v)361 MET_InitWriteField(MET_FieldRecordType * _mf, const char * _name, MET_ValueEnumType _type, size_t _length, 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, (sizeof(_mf->value) - 1));
390 ((char *)(_mf->value))[(sizeof(_mf->value) - 1)] = '\0';
391 }
392 return true;
393 }
394
395 METAIO_EXPORT
396 bool
397 MET_Write(std::ostream & fp, std::vector<MET_FieldRecordType *> * fields, char _met_SeperatorChar = '=');
398
399 METAIO_EXPORT
400 bool
401 MET_WriteFieldToFile(std::ostream & _fp, const char * _fieldName, MET_ValueEnumType _pType, size_t _n, const void * _v);
402
403 METAIO_EXPORT
404 bool
405 MET_WriteFieldToFile(std::ostream & _fp, const char * _fieldName, MET_ValueEnumType _pType, double _v);
406
407
408 METAIO_EXPORT
409 bool
410 MET_InitReadField(MET_FieldRecordType * _mf,
411 const char * _name,
412 MET_ValueEnumType _type,
413 bool _required = true,
414 int _dependsOn = -1,
415 size_t _length = 0);
416
417 METAIO_EXPORT
418 bool
419 MET_Read(std::istream & fp,
420 std::vector<MET_FieldRecordType *> * fields,
421 char _met_SeperatorChar = '=',
422 bool oneLine = false,
423 bool display_warnings = true,
424 std::vector<MET_FieldRecordType *> * newFields = nullptr);
425
426
427 METAIO_EXPORT
428 std::string
429 MET_ReadForm(std::istream & _fp);
430
431 METAIO_EXPORT
432 std::string
433 MET_ReadType(std::istream & _fp);
434
435 METAIO_EXPORT
436 char *
437 MET_ReadSubType(std::istream & _fp);
438
439 # if (METAIO_USE_NAMESPACE)
440 };
441 # endif
442
443
444 #endif
445