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 #ifdef _MSC_VER
13 #  pragma warning(disable : 4702)
14 #  pragma warning(disable : 4284)
15 #endif
16 
17 #include "metaBlob.h"
18 
19 #if (METAIO_USE_NAMESPACE)
20 namespace METAIO_NAMESPACE
21 {
22 #endif
23 
BlobPnt(int dim)24 BlobPnt::BlobPnt(int dim)
25 {
26   m_Dim = static_cast<unsigned int>(dim);
27   m_X = new float[m_Dim];
28   for (unsigned int i = 0; i < m_Dim; i++)
29   {
30     m_X[i] = 0;
31   }
32 
33   // Color is red by default
34   m_Color[0] = 1.0f;
35   m_Color[1] = 0.0f;
36   m_Color[2] = 0.0f;
37   m_Color[3] = 1.0f;
38 }
39 
~BlobPnt()40 BlobPnt::~BlobPnt()
41 {
42   delete[] m_X;
43 }
44 
45 //
46 // MedImage Constructors
47 //
MetaBlob()48 MetaBlob::MetaBlob()
49   : MetaObject()
50 {
51   META_DEBUG_PRINT( "MetaBlob()" );
52   m_NPoints = 0;
53   MetaBlob::Clear();
54 }
55 
56 //
MetaBlob(const char * _headerName)57 MetaBlob::MetaBlob(const char * _headerName)
58   : MetaObject()
59 {
60   META_DEBUG_PRINT( "MetaBlob()" );
61   m_NPoints = 0;
62   MetaBlob::Clear();
63   MetaBlob::Read(_headerName);
64 }
65 
66 //
MetaBlob(const MetaBlob * _blob)67 MetaBlob::MetaBlob(const MetaBlob * _blob)
68   : MetaObject()
69 {
70   META_DEBUG_PRINT( "MetaBlob()" );
71   m_NPoints = 0;
72   MetaBlob::Clear();
73   MetaBlob::CopyInfo(_blob);
74 }
75 
76 
77 //
MetaBlob(unsigned int dim)78 MetaBlob::MetaBlob(unsigned int dim)
79   : MetaObject(dim)
80 {
81   META_DEBUG_PRINT( "MetaBlob()" );
82   m_NPoints = 0;
83   MetaBlob::Clear();
84 }
85 
86 //
~MetaBlob()87 MetaBlob::~MetaBlob()
88 {
89   MetaBlob::Clear();
90   MetaObject::M_Destroy();
91 }
92 
93 //
94 void
PrintInfo() const95 MetaBlob::PrintInfo() const
96 {
97   MetaObject::PrintInfo();
98   std::cout << "PointDim = " << m_PointDim << std::endl;
99   std::cout << "NPoints = " << m_NPoints << std::endl;
100   char str[255];
101   MET_TypeToString(m_ElementType, str);
102   std::cout << "ElementType = " << str << std::endl;
103 }
104 
105 void
CopyInfo(const MetaObject * _object)106 MetaBlob::CopyInfo(const MetaObject * _object)
107 {
108   MetaObject::CopyInfo(_object);
109 }
110 
111 
112 void
PointDim(const char * pointDim)113 MetaBlob::PointDim(const char * pointDim)
114 {
115   strcpy(m_PointDim, pointDim);
116 }
117 
118 const char *
PointDim() const119 MetaBlob::PointDim() const
120 {
121   return m_PointDim;
122 }
123 
124 void
NPoints(size_t npnt)125 MetaBlob::NPoints(size_t npnt)
126 {
127   m_NPoints = npnt;
128 }
129 
130 size_t
NPoints() const131 MetaBlob::NPoints() const
132 {
133   return m_NPoints;
134 }
135 
136 
137 /** Clear blob information */
138 void
Clear()139 MetaBlob::Clear()
140 {
141   META_DEBUG_PRINT( "MetaBlob: Clear" );
142 
143   MetaObject::Clear();
144 
145   strcpy(m_ObjectTypeName, "Blob");
146 
147   META_DEBUG_PRINT( "MetaBlob: Clear: m_NPoints" );
148   // Delete the list of pointers to blobs.
149   auto it = m_PointList.begin();
150   while (it != m_PointList.end())
151   {
152     BlobPnt * pnt = *it;
153     ++it;
154     delete pnt;
155   }
156   m_PointList.clear();
157   m_NPoints = 0;
158   strcpy(m_PointDim, "x y z red green blue alpha");
159   m_ElementType = MET_FLOAT;
160 }
161 
162 /** Set Read fields */
163 void
M_SetupReadFields()164 MetaBlob::M_SetupReadFields()
165 {
166   META_DEBUG_PRINT( "MetaBlob: M_SetupReadFields" );
167 
168   MetaObject::M_SetupReadFields();
169 
170   MET_FieldRecordType * mF;
171 
172   mF = new MET_FieldRecordType;
173   MET_InitReadField(mF, "PointDim", MET_STRING, true);
174   m_Fields.push_back(mF);
175 
176   mF = new MET_FieldRecordType;
177   MET_InitReadField(mF, "NPoints", MET_INT, true);
178   m_Fields.push_back(mF);
179 
180   mF = new MET_FieldRecordType;
181   MET_InitReadField(mF, "ElementType", MET_STRING, true);
182   mF->required = true;
183   m_Fields.push_back(mF);
184 
185   mF = new MET_FieldRecordType;
186   MET_InitReadField(mF, "Points", MET_NONE, true);
187   mF->terminateRead = true;
188   m_Fields.push_back(mF);
189 }
190 
191 MET_ValueEnumType
ElementType() const192 MetaBlob::ElementType() const
193 {
194   return m_ElementType;
195 }
196 
197 void
ElementType(MET_ValueEnumType _elementType)198 MetaBlob::ElementType(MET_ValueEnumType _elementType)
199 {
200   m_ElementType = _elementType;
201 }
202 
203 
204 void
M_SetupWriteFields()205 MetaBlob::M_SetupWriteFields()
206 {
207   MetaObject::M_SetupWriteFields();
208 
209   MET_FieldRecordType * mF;
210 
211   char s[255];
212   mF = new MET_FieldRecordType;
213   MET_TypeToString(m_ElementType, s);
214   MET_InitWriteField(mF, "ElementType", MET_STRING, strlen(s), s);
215   m_Fields.push_back(mF);
216 
217   if (strlen(m_PointDim) > 0)
218   {
219     mF = new MET_FieldRecordType;
220     MET_InitWriteField(mF, "PointDim", MET_STRING, strlen(m_PointDim), m_PointDim);
221     m_Fields.push_back(mF);
222   }
223 
224   m_NPoints = static_cast<int>(m_PointList.size());
225   mF = new MET_FieldRecordType;
226   MET_InitWriteField(mF, "NPoints", MET_INT, static_cast<double>(m_NPoints));
227   m_Fields.push_back(mF);
228 
229   mF = new MET_FieldRecordType;
230   MET_InitWriteField(mF, "Points", MET_NONE);
231   m_Fields.push_back(mF);
232 }
233 
234 
235 bool
M_Read()236 MetaBlob::M_Read()
237 {
238   META_DEBUG_PRINT( "MetaBlob: M_Read: Loading Header" );
239 
240   if (!MetaObject::M_Read())
241   {
242     std::cout << "MetaBlob: M_Read: Error parsing file" << std::endl;
243     return false;
244   }
245 
246   META_DEBUG_PRINT( "MetaBlob: M_Read: Parsing Header" );
247 
248   MET_FieldRecordType * mF;
249 
250   mF = MET_GetFieldRecord("NPoints", &m_Fields);
251   if (mF->defined)
252   {
253     m_NPoints = static_cast<size_t>(mF->value[0]);
254   }
255 
256   mF = MET_GetFieldRecord("ElementType", &m_Fields);
257   if (mF->defined)
258   {
259     MET_StringToType(reinterpret_cast<char *>(mF->value), &m_ElementType);
260   }
261 
262 
263   mF = MET_GetFieldRecord("PointDim", &m_Fields);
264   if (mF->defined)
265   {
266     strcpy(m_PointDim, reinterpret_cast<char *>(mF->value));
267   }
268 
269   int * posDim = new int[m_NDims];
270   int   i;
271   for (i = 0; i < m_NDims; i++)
272   {
273     posDim[i] = -1;
274   }
275 
276   int     pntDim;
277   char ** pntVal = nullptr;
278   MET_StringToWordArray(m_PointDim, &pntDim, &pntVal);
279 
280 
281   for (int j = 0; j < pntDim; j++)
282   {
283     if (!strcmp(pntVal[j], "x") || !strcmp(pntVal[j], "X"))
284     {
285       posDim[0] = j;
286     }
287     if (!strcmp(pntVal[j], "y") || !strcmp(pntVal[j], "Y"))
288     {
289       posDim[1] = j;
290     }
291     if (!strcmp(pntVal[j], "z") || !strcmp(pntVal[j], "Z"))
292     {
293       posDim[2] = j;
294     }
295   }
296 
297   for (i = 0; i < pntDim; i++)
298   {
299     delete[] pntVal[i];
300   }
301 
302   delete[] pntVal;
303 
304   float v[16];
305 
306   if (m_BinaryData)
307   {
308     int elementSize;
309     MET_SizeOfType(m_ElementType, &elementSize);
310     size_t readSize = m_NPoints * (m_NDims + 4) * elementSize;
311 
312     char * _data = new char[readSize];
313     m_ReadStream->read(_data, readSize);
314 
315     auto gc = static_cast<size_t>(m_ReadStream->gcount());
316     if (gc != readSize)
317     {
318       std::cout << "MetaBlob: m_Read: data not read completely" << std::endl;
319       std::cout << "   ideal = " << readSize << " : actual = " << gc << std::endl;
320       delete[] _data;
321       delete[] posDim;
322       return false;
323     }
324 
325     i = 0;
326     int          d;
327     unsigned int k;
328     for (size_t j = 0; j < m_NPoints; j++)
329     {
330       auto * pnt = new BlobPnt(m_NDims);
331 
332       for (d = 0; d < m_NDims; d++)
333       {
334         auto * num = new float[1];
335         char * numAlias = reinterpret_cast<char *>(num);
336         for (k = 0; k < sizeof(float); k++)
337         {
338           numAlias[k] = _data[i + k];
339         }
340         float td = num[0];
341         MET_SwapByteIfSystemMSB(&td, MET_FLOAT);
342         i += sizeof(float);
343         pnt->m_X[d] = td;
344         delete[] num;
345       }
346 
347       for (d = 0; d < 4; d++)
348       {
349         auto * num = new float[1];
350         char * numAlias = reinterpret_cast<char *>(num);
351         for (k = 0; k < sizeof(float); k++)
352         {
353           numAlias[k] = _data[i + k];
354         }
355         float td = num[0];
356         MET_SwapByteIfSystemMSB(&td, MET_FLOAT);
357         i += sizeof(float);
358         pnt->m_Color[d] = td;
359         delete[] num;
360       }
361 
362       m_PointList.push_back(pnt);
363     }
364     delete[] _data;
365   }
366   else
367   {
368     for (size_t j = 0; j < m_NPoints; j++)
369     {
370       auto * pnt = new BlobPnt(m_NDims);
371 
372       for (int k = 0; k < pntDim; k++)
373       {
374         *m_ReadStream >> v[k];
375         m_ReadStream->get();
376       }
377 
378       int d;
379       for (d = 0; d < m_NDims; d++)
380       {
381         pnt->m_X[d] = v[posDim[d]];
382       }
383 
384       for (d = 0; d < 4; d++)
385       {
386         pnt->m_Color[d] = v[d + m_NDims];
387       }
388 
389       m_PointList.push_back(pnt);
390     }
391 
392     if (m_NPoints > 0)
393     {
394       char c = ' ';
395       while ((c != '\n') && (!m_ReadStream->eof()))
396       {
397         c = static_cast<char>(m_ReadStream->get()); // to avoid unrecognized characters
398       }
399     }
400   }
401 
402   delete[] posDim;
403   return true;
404 }
405 
406 
407 bool
M_Write()408 MetaBlob::M_Write()
409 {
410 
411   if (!MetaObject::M_Write())
412   {
413     std::cout << "MetaBlob: M_Read: Error parsing file" << std::endl;
414     return false;
415   }
416 
417   /** Then copy all points */
418   if (m_BinaryData)
419   {
420     PointListType::const_iterator it = m_PointList.begin();
421     PointListType::const_iterator itEnd = m_PointList.end();
422     int                           elementSize;
423     MET_SizeOfType(m_ElementType, &elementSize);
424 
425     char * data = new char[(m_NDims + 4) * m_NPoints * elementSize];
426     int    i = 0;
427     int    d;
428     while (it != itEnd)
429     {
430       for (d = 0; d < m_NDims; d++)
431       {
432         float pntX = (*it)->m_X[d];
433         MET_SwapByteIfSystemMSB(&pntX, MET_FLOAT);
434         MET_DoubleToValue(static_cast<double>(pntX), m_ElementType, data, i++);
435       }
436 
437       for (d = 0; d < 4; d++)
438       {
439         float c = (*it)->m_Color[d];
440         MET_SwapByteIfSystemMSB(&c, MET_FLOAT);
441         MET_DoubleToValue(static_cast<double>(c), m_ElementType, data, i++);
442       }
443       ++it;
444     }
445     m_WriteStream->write(data, (m_NDims + 4) * m_NPoints * elementSize);
446     m_WriteStream->write("\n", 1);
447     delete[] data;
448   }
449   else
450   {
451     PointListType::const_iterator it = m_PointList.begin();
452     PointListType::const_iterator itEnd = m_PointList.end();
453 
454     int d;
455     while (it != itEnd)
456     {
457       for (d = 0; d < m_NDims; d++)
458       {
459         *m_WriteStream << (*it)->m_X[d] << " ";
460       }
461 
462       for (d = 0; d < 4; d++)
463       {
464         *m_WriteStream << (*it)->m_Color[d] << " ";
465       }
466 
467       *m_WriteStream << std::endl;
468       ++it;
469     }
470   }
471 
472   return true;
473 }
474 
475 #if (METAIO_USE_NAMESPACE)
476 };
477 #endif
478