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