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