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 #include "metaTypes.h"
13 
14 #ifndef ITKMetaIO_METAOBJECT_H
15 #define ITKMetaIO_METAOBJECT_H
16 
17 #include "metaUtils.h"
18 #include "metaEvent.h"
19 
20 #include <string>
21 
22 #ifdef _MSC_VER
23 #pragma warning ( disable: 4251 )
24 #endif
25 
26 
27 #if (METAIO_USE_NAMESPACE)
28 namespace METAIO_NAMESPACE {
29 #endif
30 
31 class METAIO_EXPORT MetaObject
32 {
33   ////
34   //
35   // PROTECTED
36   //
37   ////
38   protected:
39 
40       typedef std::vector<MET_FieldRecordType *> FieldsContainerType;
41 
42       std::ifstream * m_ReadStream;
43       std::ofstream * m_WriteStream;
44 
45       FieldsContainerType m_Fields;
46       FieldsContainerType m_UserDefinedWriteFields;
47       FieldsContainerType m_UserDefinedReadFields;
48       FieldsContainerType m_AdditionalReadFields;
49 
50       std::string m_FileName;
51 
52       char  m_Comment[255];            // "Comment = "       ""
53 
54       char  m_ObjectTypeName[255];     // "ObjectType = "    defined by suffix
55       char  m_ObjectSubTypeName[255];  // "ObjectSubType = " defined by suffix
56 
57       int   m_NDims;                   // "NDims = "         required
58 
59       double m_Offset[10];             // "Offset = "          0,0,0
60       double m_TransformMatrix[100];   // "TransformMatrix = " 1,0,0,0,1,0,0,0,1
61       double m_CenterOfRotation[10];   // "CenterOfRotation = "  0 0 0
62 
63       MET_OrientationEnumType m_AnatomicalOrientation[10];
64       mutable char            m_OrientationAcronym[10];
65 
66       MET_DistanceUnitsEnumType m_DistanceUnits;   // "DistanceUnits = mm"
67 
68       double m_ElementSpacing[10];   // "ElementSpacing = "   0,0,0
69 
70       float m_Color[4];             // "Color = "            1.0, 0.0, 0.0, 1.0
71 
72       char  m_AcquisitionDate[255]; // "AcquisitionDate = "  "2007.03.21"
73 
74       int   m_ID;                   // "ID = "               0
75 
76       int   m_ParentID;             // "ParentID = "         -1
77 
78       char  m_Name[255];            // "Name = "             ""
79 
80       bool  m_BinaryData;           // "BinaryData = "      False
81 
82       bool  m_BinaryDataByteOrderMSB;
83 
84       std::streamoff m_CompressedDataSize;
85       // Used internally to set if the dataSize should be written
86       bool m_WriteCompressedDataSize;
87       bool m_CompressedData;
88       int  m_CompressionLevel;
89 
90       virtual void M_Destroy(void);
91 
92       virtual void M_SetupReadFields(void);
93 
94       virtual void M_SetupWriteFields(void);
95 
96       virtual bool M_Read(void);
97 
98       virtual bool M_Write(void);
99 
100       virtual void M_PrepareNewReadStream();
101 
102       MetaEvent*     m_Event;
103       //MET_FieldRecordType * M_GetFieldRecord(const char * _fieldName);
104       //int   M_GetFieldRecordNumber(const char * _fieldName);
105 
106       unsigned int m_DoublePrecision;
107 
108   /////
109   //
110   // PUBLIC
111   //
112   ////
113   public:
114 
115       ////
116       // Constructors & Destructor
117       ////
118       MetaObject(void);
119       MetaObject(const char * _fileName);
120       MetaObject(unsigned int dim);
121 
122       virtual ~MetaObject(void);
123 
124       void  FileName(const char *_fileName);
125       const char  * FileName(void) const;
126 
127       virtual void  CopyInfo(const MetaObject * _object);
128 
129       bool  Read(const char * _fileName=nullptr);
130 
131       bool  ReadStream(int _nDims, std::ifstream * _stream);
132 
133       bool  Write(const char * _fileName=nullptr);
134 
135       virtual bool  Append(const char *_headName=nullptr);
136 
137       ////
138       //
139       // Common fields
140       //
141       ////
142 
143       //    PrintMetaInfo()
144       //       Writes image parameters to stdout
145       virtual void  PrintInfo(void) const;
146 
147       //    Comment(...)
148       //       Optional Field
149       //       Arbitrary string
150       const char  * Comment(void) const;
151       void    Comment(const char * _comment);
152 
153       const char  * ObjectTypeName(void) const;
154       void    ObjectTypeName(const char * _objectTypeName);
155       const char  * ObjectSubTypeName(void) const;
156       void    ObjectSubTypeName(const char * _objectSubTypeName);
157 
158       //    NDims()
159       //       REQUIRED Field
160       //       Number of dimensions to the image
161       int   NDims(void) const;
162 
163       //    Offset(...)
164       //       Optional Field
165       //       Physical location (in millimeters and wrt machine coordinate
166       //         system or the patient) of the first element in the image
167       const double * Offset(void) const;
168       double Offset(int _i) const;
169       void  Offset(const double * _position);
170       void  Offset(int _i, double _value);
171       const double * Position(void) const;
172       double Position(int _i) const;
173       void  Position(const double * _position);
174       void  Position(int _i, double _value);
175       const double * Origin(void) const;
176       double Origin(int _i) const;
177       void  Origin(const double * _position);
178       void  Origin(int _i, double _value);
179 
180       //    TransformMatrix(...)
181       //       Optional Field
182       //       Physical orientation of the object as an NDims x NDims matrix
183       const double * TransformMatrix(void) const;
184       double TransformMatrix(int _i, int _j) const;
185       void  TransformMatrix(const double * _orientation);
186       void  TransformMatrix(int _i, int _j, double _value);
187       const double * Rotation(void) const;
188       double Rotation(int _i, int _j) const;
189       void  Rotation(const double * _orientation);
190       void  Rotation(int _i, int _j, double _value);
191       const double * Orientation(void) const;
192       double Orientation(int _i, int _j) const;
193       void  Orientation(const double * _orientation);
194       void  Orientation(int _i, int _j, double _value);
195 
196       //
197       //
198       //
199       const double * CenterOfRotation(void) const;
200       double CenterOfRotation(int _i) const;
201       void  CenterOfRotation(const double * _position);
202       void  CenterOfRotation(int _i, double _value);
203 
204       //
205       //
206       //
207       const char * DistanceUnitsName(void) const;
208       MET_DistanceUnitsEnumType DistanceUnits(void) const;
209       void DistanceUnits(MET_DistanceUnitsEnumType _distanceUnits);
210       void DistanceUnits(const char * _distanceUnits);
211 
212       const char * AnatomicalOrientationAcronym(void) const;
213       const MET_OrientationEnumType * AnatomicalOrientation(void) const;
214       MET_OrientationEnumType AnatomicalOrientation(int _dim) const;
215       void AnatomicalOrientation(const char *_ao);
216       void AnatomicalOrientation(const MET_OrientationEnumType *_ao);
217       void AnatomicalOrientation(int _dim, MET_OrientationEnumType _ao);
218       void AnatomicalOrientation(int _dim, char ao);
219 
220 
221       //    ElementSpacing(...)
222       //       Optional Field
223       //       Physical Spacing (in same units as position)
224       const double * ElementSpacing(void) const;
225       double ElementSpacing(int _i) const;
226       void  ElementSpacing(const double * _elementSpacing);
227       void  ElementSpacing(const float * _elementSpacing);
228       void  ElementSpacing(int _i, double _value);
229 
230       //    Name(...)
231       //       Optional Field
232       //       Name of the current metaObject
233       void  Name(const char *_name);
234       const char  * Name(void) const;
235 
236       //    Color(...)
237       //       Optional Field
238       //       Color of the current metaObject
239       const float * Color(void) const;
240       void  Color(float _r, float _g, float _b, float _a);
241       void  Color(const float * _color);
242 
243       //    ID(...)
244       //       Optional Field
245       //       ID number of the current metaObject
246       void ID(int _id);
247       int  ID(void) const;
248 
249       //    ParentID(...)
250       //       Optional Field
251       //       ID number of the parent  metaObject
252       void  ParentID(int _parentId);
253       int   ParentID(void) const;
254 
255       //    AcquisitionDate(...)
256       //       Optional Field
257       //       YYYY.MM.DD is the recommended format
258       void  AcquisitionDate(const char * _acquisitionDate);
259       const char *  AcquisitionDate(void) const;
260 
261       //    BinaryData(...)
262       //       Optional Field
263       //       Data is binary or not
264       void  BinaryData(bool _binaryData);
265       bool  BinaryData(void) const;
266 
267       void  BinaryDataByteOrderMSB(bool _binaryDataByteOrderMSB);
268       bool  BinaryDataByteOrderMSB(void) const;
269 
270 
271       void  CompressedData(bool _compressedData);
272       bool  CompressedData(void) const;
273 
274       // Compression level 0-9. 0 = no compression.
275       void CompressionLevel(int _compressionLevel);
276       int CompressionLevel() const;
277 
278       virtual void Clear(void);
279 
280       void ClearFields(void);
281 
282       void ClearAdditionalFields(void);
283 
284       bool InitializeEssential(int _nDims);
285 
286       //
287       //
288       // User's field definitions
289       bool AddUserField(const char* _fieldName, MET_ValueEnumType _type,
290                         int _length=0, bool _required=true,
291                         int _dependsOn=-1);
292 
293       // find a field record in a field vector
FindFieldRecord(FieldsContainerType & container,const char * fieldName)294       MET_FieldRecordType *FindFieldRecord(FieldsContainerType &container,
295                                            const char *fieldName)
296       {
297         FieldsContainerType::iterator it;
298         for(it = container.begin();
299             it != container.end();
300             ++it)
301           {
302           if(strcmp((*it)->name,fieldName) == 0)
303             {
304             return (*it);
305             }
306           }
307         return nullptr;
308       }
309 
310       // Add a user's field
311       template <class T>
312       bool AddUserField(const char* _fieldName, MET_ValueEnumType _type,
313                         int _length, T *_v, bool _required=true,
314                         int _dependsOn=-1 )
315         {
316         // don't add the same field twice. In the unlikely event
317         // a field of the same name gets added more than once,
318         // over-write the existing FieldRecord
319         bool duplicate(true);
320         MET_FieldRecordType* mFw =
321           this->FindFieldRecord(m_UserDefinedWriteFields,
322                                 _fieldName);
323         if(mFw == nullptr)
324           {
325           duplicate = false;
326           mFw = new MET_FieldRecordType;
327           }
328         MET_InitWriteField(mFw, _fieldName, _type, _length, _v);
329         if(!duplicate)
330           {
331           m_UserDefinedWriteFields.push_back(mFw);
332           }
333 
334         duplicate = true;
335         MET_FieldRecordType* mFr =
336           this->FindFieldRecord(m_UserDefinedReadFields,
337                                 _fieldName);
338         if(mFr == nullptr)
339           {
340           duplicate = false;
341           mFr = new MET_FieldRecordType;
342           }
343 
344         MET_InitReadField(mFr,_fieldName, _type, _required, _dependsOn,
345           _length);
346         if(!duplicate)
347           {
348           m_UserDefinedReadFields.push_back(mFr);
349           }
350         return true;
351         }
352 
353       // Clear UserFields
354       void ClearUserFields();
355 
356       // Get the user field
357       void* GetUserField(const char* _name);
358 
359       int GetNumberOfAdditionalReadFields();
360       char * GetAdditionalReadFieldName( int i );
361       char * GetAdditionalReadFieldValue( int i );
362       int GetAdditionalReadFieldValueLength( int i );
363 
364       //
SetEvent(MetaEvent * event)365       void SetEvent(MetaEvent* event) {m_Event = event;}
366 
367       // Set the double precision for writing
SetDoublePrecision(unsigned int precision)368       void SetDoublePrecision(unsigned int precision)
369         {
370         m_DoublePrecision = precision;
371         }
GetDoublePrecision()372       unsigned int GetDoublePrecision()
373         {
374         return m_DoublePrecision;
375         }
376 
377 };
378 
379 #if (METAIO_USE_NAMESPACE)
380 };
381 #endif
382 
383 #endif
384