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 "metaArray.h"
13
14 #ifdef _MSC_VER
15 #pragma warning(disable:4702)
16 #pragma warning(disable:4996)
17 #endif
18
19 #include <stdio.h>
20 #include <ctype.h>
21 #include <string>
22 #include <string.h> // for memcpy
23 #include <math.h>
24
25 #if (METAIO_USE_NAMESPACE)
26 namespace METAIO_NAMESPACE {
27 #endif
28
29
30 //
31 // MetaArray Constructors
32 //
33 MetaArray::
MetaArray()34 MetaArray()
35 :MetaForm()
36 {
37 if(META_DEBUG)
38 {
39 METAIO_STREAM::cout << "MetaArray()" << METAIO_STREAM::endl;
40 }
41
42 m_ElementData = NULL;
43 m_AutoFreeElementData = false;
44
45 m_CompressedElementDataSize = 0;
46
47 strcpy(m_ElementDataFileName, "");
48
49 MetaArray::Clear();
50 }
51
52 //
53 MetaArray::
MetaArray(const char * _headerName)54 MetaArray(const char *_headerName)
55 :MetaForm()
56 {
57 if(META_DEBUG)
58 {
59 METAIO_STREAM::cout << "MetaArray()" << METAIO_STREAM::endl;
60 }
61
62 m_ElementData = NULL;
63 m_AutoFreeElementData = false;
64
65 m_CompressedElementDataSize = 0;
66
67 strcpy(m_ElementDataFileName, "");
68
69 MetaArray::Clear();
70
71 MetaArray::Read(_headerName);
72 }
73
74 //
75 MetaArray::
MetaArray(MetaArray * _vector,bool _allocateElementData,bool _autoFreeElementData)76 MetaArray(MetaArray *_vector,
77 bool _allocateElementData,
78 bool _autoFreeElementData)
79 :MetaForm()
80 {
81 if(META_DEBUG)
82 {
83 METAIO_STREAM::cout << "MetaArray()" << METAIO_STREAM::endl;
84 }
85
86 m_ElementData = NULL;
87 m_AutoFreeElementData = false;
88
89 m_CompressedElementDataSize = 0;
90
91 strcpy(m_ElementDataFileName, "");
92
93 MetaArray::Clear();
94
95 InitializeEssential(_vector->Length(),
96 _vector->ElementType(),
97 _vector->ElementNumberOfChannels(),
98 _vector->ElementData(),
99 _allocateElementData,
100 _autoFreeElementData);
101
102 CopyInfo(_vector);
103 }
104
105 //
106 MetaArray::
MetaArray(int _length,MET_ValueEnumType _elementType,int _elementNumberOfChannels,void * _elementData,bool _allocateElementData,bool _autoFreeElementData)107 MetaArray(int _length,
108 MET_ValueEnumType _elementType,
109 int _elementNumberOfChannels,
110 void *_elementData,
111 bool _allocateElementData,
112 bool _autoFreeElementData)
113 :MetaForm()
114 {
115 if(META_DEBUG)
116 {
117 METAIO_STREAM::cout << "MetaArray()" << METAIO_STREAM::endl;
118 }
119
120 m_ElementData = NULL;
121 m_AutoFreeElementData = false;
122
123 m_CompressedElementDataSize = 0;
124
125 strcpy(m_ElementDataFileName, "");
126
127 MetaArray::Clear();
128
129 InitializeEssential(_length,
130 _elementType,
131 _elementNumberOfChannels,
132 _elementData,
133 _allocateElementData,
134 _autoFreeElementData);
135 }
136
137 //
138 MetaArray::
~MetaArray()139 ~MetaArray()
140 {
141 M_Destroy();
142 }
143
144 //
145 void MetaArray::
PrintInfo() const146 PrintInfo() const
147 {
148 MetaForm::PrintInfo();
149
150 METAIO_STREAM::cout << "Length = " << (int)m_Length << METAIO_STREAM::endl;
151
152 METAIO_STREAM::cout << "BinaryData = "
153 << ((m_BinaryData)?"True":"False")
154 << METAIO_STREAM::endl;
155
156 METAIO_STREAM::cout << "BinaryDataByteOrderMSB = "
157 << ((m_BinaryDataByteOrderMSB)?"True":"False")
158 << METAIO_STREAM::endl;
159
160 char str[255];
161 MET_TypeToString(m_ElementType, str);
162 METAIO_STREAM::cout << "ElementType = " << str << METAIO_STREAM::endl;
163
164 METAIO_STREAM::cout << "ElementNumberOfChannels = "
165 << m_ElementNumberOfChannels
166 << METAIO_STREAM::endl;
167
168 METAIO_STREAM::cout << "AutoFreeElementData = "
169 << ((m_AutoFreeElementData)?"True":"False")
170 << METAIO_STREAM::endl;
171
172 METAIO_STREAM::cout << "CompressedElementDataSize = "
173 << m_CompressedElementDataSize
174 << METAIO_STREAM::endl;
175
176 METAIO_STREAM::cout << "ElementDataFileName = " << m_ElementDataFileName
177 << METAIO_STREAM::endl;
178
179 METAIO_STREAM::cout << "ElementData = "
180 << ((m_ElementData==NULL)?"NULL":"Valid")
181 << METAIO_STREAM::endl;
182 }
183
184 void MetaArray::
CopyInfo(const MetaForm * _form)185 CopyInfo(const MetaForm * _form)
186 {
187 MetaForm::CopyInfo(_form);
188 }
189
190 void MetaArray::
Clear(void)191 Clear(void)
192 {
193 if(META_DEBUG)
194 {
195 METAIO_STREAM::cout << "MetaArray: Clear" << METAIO_STREAM::endl;
196 }
197
198 m_Length = 0;
199
200 m_ElementType = MET_NONE;
201
202 m_ElementNumberOfChannels = 1;
203
204 m_CompressedElementDataSize = 0;
205
206 strcpy(m_ElementDataFileName, "");
207
208 if(m_AutoFreeElementData)
209 {
210 if(m_ElementData != NULL)
211 {
212 delete [] (char *)m_ElementData;
213 }
214 }
215 m_ElementData = NULL;
216 m_AutoFreeElementData = true;
217
218 MetaForm::Clear();
219 }
220
221 bool MetaArray::
InitializeEssential(int _length,MET_ValueEnumType _elementType,int _elementNumberOfChannels,void * _elementData,bool _allocateElementData,bool _autoFreeElementData)222 InitializeEssential(int _length,
223 MET_ValueEnumType _elementType,
224 int _elementNumberOfChannels,
225 void * _elementData,
226 bool _allocateElementData,
227 bool _autoFreeElementData)
228 {
229 if(META_DEBUG)
230 {
231 METAIO_STREAM::cout << "MetaArray: Initialize" << METAIO_STREAM::endl;
232 }
233
234 MetaForm::InitializeEssential();
235
236 bool result = true;
237
238 if(m_Length != _length ||
239 m_ElementType != _elementType ||
240 m_ElementNumberOfChannels != _elementNumberOfChannels ||
241 _elementData != NULL ||
242 _allocateElementData == true)
243 {
244 if(m_AutoFreeElementData)
245 {
246 if(m_ElementData != NULL)
247 {
248 delete [] (char *)m_ElementData;
249 }
250 }
251 m_ElementData = NULL;
252
253 m_Length = _length;
254 m_ElementType = _elementType;
255 m_ElementNumberOfChannels = _elementNumberOfChannels;
256
257 if(_elementData != NULL)
258 {
259 m_ElementData = (void *)_elementData;
260 }
261 else
262 {
263 if(_allocateElementData)
264 {
265 result = AllocateElementData(_autoFreeElementData);
266 }
267 else
268 {
269 m_ElementData = NULL;
270 }
271 }
272
273 m_AutoFreeElementData = _autoFreeElementData;
274 }
275
276 return result;
277 }
278
279 bool MetaArray::
AllocateElementData(bool _autoFreeElementData)280 AllocateElementData(bool _autoFreeElementData)
281 {
282 if(m_AutoFreeElementData)
283 {
284 if(m_ElementData != NULL)
285 {
286 delete [] (char *)m_ElementData;
287 }
288 }
289 m_ElementData = NULL;
290
291 m_AutoFreeElementData = _autoFreeElementData;
292
293 int eSize;
294 MET_SizeOfType(m_ElementType, &eSize);
295 m_ElementData = new char[m_Length*m_ElementNumberOfChannels*eSize];
296
297 if(m_ElementData != NULL)
298 {
299 return true;
300 }
301 else
302 {
303 return false;
304 }
305 }
306
307 int MetaArray::
Length(void) const308 Length(void) const
309 {
310 return m_Length;
311 }
312
313 void MetaArray::
Length(int _length)314 Length(int _length)
315 {
316 if(m_Length != _length)
317 {
318 InitializeEssential(_length, m_ElementType, m_ElementNumberOfChannels);
319 }
320 }
321
322 int MetaArray::
NDims(void) const323 NDims(void) const
324 {
325 return Length();
326 }
327
328 void MetaArray::
NDims(int _length)329 NDims(int _length)
330 {
331 Length(_length);
332 }
333
334 MET_ValueEnumType MetaArray::
ElementType(void) const335 ElementType(void) const
336 {
337 return m_ElementType;
338 }
339
340 void MetaArray::
ElementType(MET_ValueEnumType _elementType)341 ElementType(MET_ValueEnumType _elementType)
342 {
343 if(m_ElementType != _elementType)
344 {
345 InitializeEssential(m_Length, _elementType, m_ElementNumberOfChannels);
346 }
347 }
348
349 int MetaArray::
ElementNumberOfChannels(void) const350 ElementNumberOfChannels(void) const
351 {
352 return m_ElementNumberOfChannels;
353 }
354
355 void MetaArray::
ElementNumberOfChannels(int _elementNumberOfChannels)356 ElementNumberOfChannels(int _elementNumberOfChannels)
357 {
358 if(m_ElementNumberOfChannels != _elementNumberOfChannels)
359 {
360 InitializeEssential(m_Length, m_ElementType, _elementNumberOfChannels);
361 }
362 }
363
364 void MetaArray::
ElementByteOrderSwap(void)365 ElementByteOrderSwap(void)
366 {
367 if(META_DEBUG)
368 {
369 METAIO_STREAM::cout << "MetaArray: ElementByteOrderSwap"
370 << METAIO_STREAM::endl;
371 }
372
373 int eSize;
374 MET_SizeOfType(m_ElementType, &eSize);
375 switch(eSize)
376 {
377 default:
378 case 0:
379 case 1:
380 {
381 break;
382 }
383 case 2:
384 {
385 int i;
386 for(i=0; i<m_Length*m_ElementNumberOfChannels; i++)
387 {
388 ((MET_USHORT_TYPE *)m_ElementData)[i] =
389 MET_ByteOrderSwapShort(((MET_USHORT_TYPE *)m_ElementData)[i]);
390 }
391 break;
392 }
393 case 4:
394 {
395 int i;
396 for(i=0; i<m_Length*m_ElementNumberOfChannels; i++)
397 {
398 ((MET_UINT_TYPE *)m_ElementData)[i] =
399 MET_ByteOrderSwapLong(((MET_UINT_TYPE *)m_ElementData)[i]);
400 }
401 break;
402 }
403 case 8:
404 {
405 int i;
406 char* data = (char*)m_ElementData;
407 for(i=0; i<m_Length*m_ElementNumberOfChannels; i++)
408 {
409 MET_ByteOrderSwap8(data);
410 data += 8;
411 }
412 break;
413 }
414 }
415 m_BinaryDataByteOrderMSB = !m_BinaryDataByteOrderMSB;
416 }
417
418 bool MetaArray::
ElementByteOrderFix(void)419 ElementByteOrderFix(void)
420 {
421 if(m_BinaryDataByteOrderMSB != MET_SystemByteOrderMSB())
422 {
423 ElementByteOrderSwap();
424 return true;
425 }
426 return true;
427 }
428
429 bool MetaArray::
ConvertElementDataTo(MET_ValueEnumType _toElementType,double _fromMin,double _fromMax,double _toMin,double _toMax)430 ConvertElementDataTo(MET_ValueEnumType _toElementType,
431 double _fromMin, double _fromMax,
432 double _toMin, double _toMax)
433 {
434 if(m_ElementData == NULL)
435 {
436 return false;
437 }
438
439 ElementByteOrderFix();
440
441 void * curBuffer = m_ElementData;
442 MET_ValueEnumType curElementType = m_ElementType;
443 bool curAutoFreeElementData = m_AutoFreeElementData;
444
445 if(m_ElementType != _toElementType)
446 {
447 m_ElementData = NULL;
448 m_ElementType = _toElementType;
449 }
450
451 ImportBufferToElementData(curBuffer, curElementType,
452 _fromMin, _fromMax,
453 _toMin, _toMax );
454
455 if(m_ElementType != _toElementType)
456 {
457 if(curAutoFreeElementData)
458 {
459 delete [] (char *)curBuffer;
460 }
461 }
462
463 return true;
464 }
465
466 bool MetaArray::
ImportBufferToElementData(const void * _fromBuffer,MET_ValueEnumType _fromElementType,double _fromMin,double _fromMax,double _toMin,double _toMax)467 ImportBufferToElementData(const void * _fromBuffer,
468 MET_ValueEnumType _fromElementType,
469 double _fromMin, double _fromMax,
470 double _toMin, double _toMax)
471 {
472 if(m_ElementData == NULL)
473 {
474 AllocateElementData(true);
475 }
476
477 if(_fromMin == 0 && _fromMax == 0)
478 {
479 MET_ValueToDouble(_fromElementType, _fromBuffer, 0, &_fromMin);
480 _fromMax = _fromMin;
481
482 int i;
483 for(i=0; i<m_Length*m_ElementNumberOfChannels; i++)
484 {
485 double tf;
486 MET_ValueToDouble(_fromElementType, _fromBuffer, i, &tf);
487 if(tf < _fromMin)
488 {
489 _fromMin = tf;
490 }
491 else if(tf > _fromMax)
492 {
493 _fromMax = tf;
494 }
495 }
496 }
497
498 if(_toMin == 0 && _toMax == 0)
499 {
500 _toMin = _fromMin;
501 _toMax = _fromMax;
502 }
503
504 for(int i=0; i<m_Length*m_ElementNumberOfChannels; i++)
505 {
506 MET_ValueToValue(_fromElementType, _fromBuffer, i,
507 m_ElementType, m_ElementData,
508 _fromMin, _fromMax,
509 _toMin, _toMax);
510 }
511
512 return true;
513 }
514
515
516 //
517 //
518 //
519 bool MetaArray::
AutoFreeElementData(void) const520 AutoFreeElementData(void) const
521 {
522 return m_AutoFreeElementData;
523 }
524
525 void MetaArray::
AutoFreeElementData(bool _autoFreeElementData)526 AutoFreeElementData(bool _autoFreeElementData)
527 {
528 m_AutoFreeElementData = _autoFreeElementData;
529 }
530
531
532 //
533 //
534 //
535 const char * MetaArray::
ElementDataFileName(void) const536 ElementDataFileName(void) const
537 {
538 return m_ElementDataFileName;
539 }
540
541 void MetaArray::
ElementDataFileName(const char * _elementDataFileName)542 ElementDataFileName(const char * _elementDataFileName)
543 {
544 strcpy(m_ElementDataFileName, _elementDataFileName);
545 }
546
547
548 //
549 //
550 //
551 void * MetaArray::
ElementData(void)552 ElementData(void)
553 {
554 return m_ElementData;
555 }
556
557 double MetaArray::
ElementData(int _i) const558 ElementData(int _i) const
559 {
560 double tf = 0;
561 MET_ValueToDouble(m_ElementType, m_ElementData, _i, &tf);
562
563 return tf;
564 }
565
566 void MetaArray::
ElementData(void * _elementData,bool _arrayControlsElementData)567 ElementData(void * _elementData, bool _arrayControlsElementData)
568 {
569 if(m_AutoFreeElementData)
570 {
571 delete [] (char *)m_ElementData;
572 }
573 m_ElementData = _elementData;
574 m_AutoFreeElementData = _arrayControlsElementData;
575 }
576
577 bool MetaArray::
ElementData(int _i,double _v)578 ElementData(int _i, double _v)
579 {
580 if(_i<m_Length*m_ElementNumberOfChannels)
581 {
582 MET_DoubleToValue(_v, m_ElementType, m_ElementData, _i);
583 return true;
584 }
585 return false;
586 }
587
588
589 //
590 //
591 //
592 bool MetaArray::
CanRead(const char * _headerName) const593 CanRead(const char *_headerName) const
594 {
595 // First check the extension
596 METAIO_STL::string fname = _headerName;
597 if( fname == "" )
598 {
599 return false;
600 }
601
602 bool extensionFound = false;
603
604 METAIO_STL::string::size_type stringPos = fname.rfind(".mva");
605 if ((stringPos != METAIO_STL::string::npos)
606 && (stringPos == fname.length() - 4))
607 {
608 extensionFound = true;
609 }
610
611 stringPos = fname.rfind(".mvh");
612 if ((stringPos != METAIO_STL::string::npos)
613 && (stringPos == fname.length() - 4))
614 {
615 extensionFound = true;
616 }
617
618 if( !extensionFound )
619 {
620 return false;
621 }
622
623 // Now check the file content
624 METAIO_STREAM::ifstream inputStream;
625
626 #ifdef __sgi
627 inputStream.open( _headerName, METAIO_STREAM::ios::in );
628 #else
629 inputStream.open( _headerName, METAIO_STREAM::ios::in |
630 METAIO_STREAM::ios::binary );
631 #endif
632
633 if( !inputStream.rdbuf()->is_open() )
634 {
635 return false;
636 }
637
638 bool result = !strncmp(MET_ReadForm(inputStream).c_str(), "Array", 5);
639
640 inputStream.close();
641
642 return result;
643 }
644
645
646 bool MetaArray::
Read(const char * _headerName,bool _readElements,void * _elementDataBuffer,bool _autoFreeElementData)647 Read(const char *_headerName, bool _readElements,
648 void * _elementDataBuffer, bool _autoFreeElementData)
649 {
650 if(_headerName != NULL)
651 {
652 strcpy(m_FileName, _headerName);
653 }
654
655 METAIO_STREAM::ifstream * tmpStream = new METAIO_STREAM::ifstream;
656
657 #ifdef __sgi
658 tmpStream->open(m_FileName, METAIO_STREAM::ios::in );
659 #else
660 tmpStream->open(m_FileName, METAIO_STREAM::ios::in |
661 METAIO_STREAM::ios::binary);
662 #endif
663
664 if(!tmpStream->rdbuf()->is_open())
665 {
666 METAIO_STREAM::cout << "MetaArray: Read: Cannot open file _"
667 << m_FileName << "_" << METAIO_STREAM::endl;
668 delete tmpStream;
669 return false;
670 }
671
672 bool result = ReadStream(tmpStream, _readElements,
673 _elementDataBuffer, _autoFreeElementData);
674
675 if(_headerName != NULL)
676 {
677 strcpy(m_FileName, _headerName);
678 }
679
680 tmpStream->close();
681
682 delete tmpStream;
683
684 return result;
685 }
686
687
688 bool MetaArray::
CanReadStream(METAIO_STREAM::ifstream * _stream) const689 CanReadStream(METAIO_STREAM::ifstream * _stream) const
690 {
691 if(!strncmp(MET_ReadForm(*_stream).c_str(), "Array", 5))
692 {
693 return true;
694 }
695 return false;
696 }
697
698 bool MetaArray::
ReadStream(METAIO_STREAM::ifstream * _stream,bool _readElements,void * _elementDataBuffer,bool _autoFreeElementData)699 ReadStream(METAIO_STREAM::ifstream * _stream, bool _readElements,
700 void * _elementDataBuffer, bool _autoFreeElementData)
701 {
702 if(META_DEBUG)
703 {
704 METAIO_STREAM::cout << "MetaArray: ReadStream" << METAIO_STREAM::endl;
705 }
706
707 M_Destroy();
708
709 Clear();
710
711 M_SetupReadFields();
712
713 if(m_ReadStream)
714 {
715 METAIO_STREAM::cout << "MetaArray: ReadStream: two files open?"
716 << METAIO_STREAM::endl;
717 delete m_ReadStream;
718 }
719
720 m_ReadStream = _stream;
721
722 if(!M_Read())
723 {
724 METAIO_STREAM::cout << "MetaArray: Read: Cannot parse file"
725 << METAIO_STREAM::endl;
726 m_ReadStream = NULL;
727 return false;
728 }
729
730 InitializeEssential(m_Length,
731 m_ElementType,
732 m_ElementNumberOfChannels,
733 _elementDataBuffer,
734 true,
735 _autoFreeElementData);
736
737 bool usePath;
738 char pathName[255];
739 char fName[255];
740 usePath = MET_GetFilePath(m_FileName, pathName);
741
742 if(_readElements)
743 {
744 if(!strcmp("Local", m_ElementDataFileName) ||
745 !strcmp("LOCAL", m_ElementDataFileName) ||
746 !strcmp("local", m_ElementDataFileName))
747 {
748 M_ReadElements(m_ReadStream, m_ElementData, m_Length);
749 }
750 else
751 {
752 if(usePath)
753 {
754 sprintf(fName, "%s%s", pathName, m_ElementDataFileName);
755 }
756 else
757 {
758 strcpy(fName, m_ElementDataFileName);
759 }
760 METAIO_STREAM::ifstream* readStreamTemp = new METAIO_STREAM::ifstream;
761
762 #ifdef __sgi
763 readStreamTemp->open(fName, METAIO_STREAM::ios::in);
764 #else
765 readStreamTemp->open(fName, METAIO_STREAM::ios::binary |
766 METAIO_STREAM::ios::in);
767 #endif
768 if(!readStreamTemp->rdbuf()->is_open())
769 {
770 METAIO_STREAM::cout << "MetaArray: Read: Cannot open data file"
771 << METAIO_STREAM::endl;
772 m_ReadStream = NULL;
773 return false;
774 }
775 if(_readElements)
776 {
777 M_ReadElements(readStreamTemp, m_ElementData, m_Length);
778 }
779 readStreamTemp->close();
780 delete readStreamTemp;
781 }
782 }
783
784 m_ReadStream = NULL;
785
786 return true;
787 }
788
789 //
790 //
791 //
792 //
793
794 bool MetaArray::
Write(const char * _headName,const char * _dataName,bool _writeElements,const void * _constElementData)795 Write(const char *_headName, const char *_dataName, bool _writeElements,
796 const void *_constElementData)
797 {
798 if(_headName != NULL && strlen(_headName)>1)
799 {
800 FileName(_headName);
801 }
802
803 bool tmpDataFileName = false;
804 if( _dataName != NULL &&
805 strlen(_dataName) > 1 )
806 {
807 tmpDataFileName = true;
808 ElementDataFileName(_dataName);
809 }
810 else
811 {
812 if( strlen(m_ElementDataFileName) == 0 )
813 {
814 tmpDataFileName = true;
815 }
816 }
817
818 int sPtr = 0;
819 MET_GetFileSuffixPtr(m_FileName, &sPtr);
820 if( !strcmp(&(m_FileName[sPtr]), "mvh") )
821 {
822 MET_SetFileSuffix(m_FileName, "mvh");
823 if( strlen(m_ElementDataFileName) == 0 ||
824 !strcmp(m_ElementDataFileName, "LOCAL") )
825 {
826 ElementDataFileName(m_FileName);
827 }
828 if(m_CompressedData)
829 {
830 MET_SetFileSuffix(m_ElementDataFileName, "zmvd");
831 }
832 else
833 {
834 MET_SetFileSuffix(m_ElementDataFileName, "mvd");
835 }
836 }
837 else
838 {
839 MET_SetFileSuffix(m_FileName, "mva");
840 ElementDataFileName("LOCAL");
841 }
842
843 char pathName[255];
844 bool usePath = MET_GetFilePath(m_FileName, pathName);
845 if(usePath)
846 {
847 char elementPathName[255];
848 MET_GetFilePath(m_ElementDataFileName, elementPathName);
849 if(!strcmp(pathName, elementPathName))
850 {
851 strcpy(elementPathName, &m_ElementDataFileName[strlen(pathName)]);
852 strcpy(m_ElementDataFileName, elementPathName);
853 }
854 }
855
856 METAIO_STREAM::ofstream * tmpWriteStream = new METAIO_STREAM::ofstream;
857
858 // Some older sgi compilers have a error in the ofstream constructor
859 // that requires a file to exist for output
860 #ifdef __sgi
861 {
862 METAIO_STREAM::ofstream tFile(m_FileName, METAIO_STREAM::ios::out);
863 tFile.close();
864 }
865 tmpWriteStream->open(m_FileName, METAIO_STREAM::ios::out);
866 #else
867 tmpWriteStream->open(m_FileName, METAIO_STREAM::ios::binary |
868 METAIO_STREAM::ios::out);
869 #endif
870
871 if(!tmpWriteStream->rdbuf()->is_open())
872 {
873 if(tmpDataFileName)
874 {
875 ElementDataFileName("");
876 }
877 delete tmpWriteStream;
878 return false;
879 }
880
881 bool result = WriteStream(tmpWriteStream, _writeElements, _constElementData);
882
883 if(tmpDataFileName)
884 {
885 ElementDataFileName("");
886 }
887
888 tmpWriteStream->close();
889
890 delete tmpWriteStream;
891
892 return result;
893 }
894
895 bool MetaArray::
WriteStream(METAIO_STREAM::ofstream * _stream,bool _writeElements,const void * _constElementData)896 WriteStream(METAIO_STREAM::ofstream * _stream, bool _writeElements,
897 const void *_constElementData)
898 {
899 if(m_WriteStream != NULL)
900 {
901 METAIO_STREAM::cout << "MetaArray: WriteStream: two files open?"
902 << METAIO_STREAM::endl;
903 delete m_WriteStream;
904 }
905
906 m_WriteStream = _stream;
907
908 unsigned char * compressedElementData = NULL;
909 if(m_CompressedData)
910 {
911 int elementSize;
912 MET_SizeOfType(m_ElementType, &elementSize);
913 int elementNumberOfBytes = elementSize*m_ElementNumberOfChannels;
914
915 if(_constElementData == NULL)
916 {
917 compressedElementData = MET_PerformCompression(
918 (const unsigned char *)m_ElementData,
919 m_Length * elementNumberOfBytes,
920 & m_CompressedElementDataSize);
921 }
922 else
923 {
924 compressedElementData = MET_PerformCompression(
925 (const unsigned char *)_constElementData,
926 m_Length * elementNumberOfBytes,
927 & m_CompressedElementDataSize);
928 }
929 }
930
931 M_SetupWriteFields();
932
933 M_Write();
934
935 if(_writeElements)
936 {
937 if(m_CompressedData)
938 {
939 M_WriteElements(m_WriteStream,
940 compressedElementData,
941 m_CompressedElementDataSize);
942
943 delete [] compressedElementData;
944 }
945 else
946 {
947 int elementSize;
948 MET_SizeOfType(m_ElementType, &elementSize);
949 int elementNumberOfBytes = elementSize*m_ElementNumberOfChannels;
950
951 if(_constElementData != NULL)
952 {
953 M_WriteElements(m_WriteStream,
954 _constElementData,
955 elementNumberOfBytes * m_Length);
956 }
957 else
958 {
959 M_WriteElements(m_WriteStream,
960 m_ElementData,
961 elementNumberOfBytes * m_Length);
962 }
963 }
964 }
965
966 m_WriteStream->flush();
967
968 m_WriteStream = NULL;
969
970 return true;
971 }
972
973 void MetaArray::
M_Destroy(void)974 M_Destroy(void)
975 {
976 if(m_AutoFreeElementData && m_ElementData != NULL)
977 {
978 delete [] (char *)m_ElementData;
979 }
980 m_ElementData = NULL;
981
982 MetaForm::M_Destroy();
983 }
984
985 void MetaArray::
M_SetupReadFields(void)986 M_SetupReadFields(void)
987 {
988 if(META_DEBUG)
989 {
990 METAIO_STREAM::cout << "MetaArray: M_SetupReadFields"
991 << METAIO_STREAM::endl;
992 }
993
994 MetaForm::M_SetupReadFields();
995
996 MET_FieldRecordType * mF;
997
998 mF = new MET_FieldRecordType;
999 MET_InitReadField(mF, "Length", MET_INT, false);
1000 m_Fields.push_back(mF);
1001
1002 mF = new MET_FieldRecordType;
1003 MET_InitReadField(mF, "NDims", MET_INT, false);
1004 m_Fields.push_back(mF);
1005
1006 mF = new MET_FieldRecordType;
1007 MET_InitReadField(mF, "ElementNumberOfChannels", MET_INT, false);
1008 m_Fields.push_back(mF);
1009
1010 mF = new MET_FieldRecordType;
1011 MET_InitReadField(mF, "ElementType", MET_STRING, true);
1012 mF->required = true;
1013 m_Fields.push_back(mF);
1014
1015 mF = new MET_FieldRecordType;
1016 MET_InitReadField(mF, "ElementDataFile", MET_STRING, true);
1017 mF->required = true;
1018 mF->terminateRead = true;
1019 m_Fields.push_back(mF);
1020 }
1021
1022 void MetaArray::
M_SetupWriteFields(void)1023 M_SetupWriteFields(void)
1024 {
1025 strcpy(m_FormTypeName, "Array");
1026 MetaForm::M_SetupWriteFields();
1027
1028 MET_FieldRecordType * mF;
1029
1030 mF = new MET_FieldRecordType;
1031 MET_InitWriteField(mF, "Length", MET_INT, m_Length);
1032 m_Fields.push_back(mF);
1033
1034 if(m_ElementNumberOfChannels>1)
1035 {
1036 mF = new MET_FieldRecordType;
1037 MET_InitWriteField(mF, "ElementNumberOfChannels", MET_INT,
1038 m_ElementNumberOfChannels);
1039 m_Fields.push_back(mF);
1040 }
1041
1042 char s[80];
1043 mF = new MET_FieldRecordType;
1044 MET_TypeToString(m_ElementType, s);
1045 MET_InitWriteField(mF, "ElementType", MET_STRING, strlen(s), s);
1046 m_Fields.push_back(mF);
1047
1048 mF = new MET_FieldRecordType;
1049 MET_InitWriteField(mF, "ElementDataFile", MET_STRING,
1050 strlen(m_ElementDataFileName),
1051 m_ElementDataFileName);
1052 mF->terminateRead = true;
1053 m_Fields.push_back(mF);
1054 }
1055
1056
1057 bool MetaArray::
M_Read(void)1058 M_Read(void)
1059 {
1060 if(META_DEBUG)
1061 {
1062 METAIO_STREAM::cout << "MetaArray: M_Read: Loading Header"
1063 << METAIO_STREAM::endl;
1064 }
1065 if(!MetaForm::M_Read())
1066 {
1067 METAIO_STREAM::cout << "MetaArray: M_Read: Error parsing file"
1068 << METAIO_STREAM::endl;
1069 return false;
1070 }
1071
1072 if(META_DEBUG)
1073 {
1074 METAIO_STREAM::cout << "MetaArray: M_Read: Parsing Header"
1075 << METAIO_STREAM::endl;
1076 }
1077 MET_FieldRecordType * mF;
1078
1079 mF = MET_GetFieldRecord("Length", &m_Fields);
1080 if(mF && mF->defined)
1081 {
1082 m_Length = (int)mF->value[0];
1083 }
1084 else
1085 {
1086 mF = MET_GetFieldRecord("NDims", &m_Fields);
1087 if(mF && mF->defined)
1088 {
1089 m_Length = (int)mF->value[0];
1090 }
1091 else
1092 {
1093 METAIO_STREAM::cout << "MetaArray: M_Read: Error: Length required"
1094 << METAIO_STREAM::endl;
1095 return false;
1096 }
1097 }
1098
1099 mF = MET_GetFieldRecord("ElementNumberOfChannels", &m_Fields);
1100 if(mF && mF->defined)
1101 {
1102 m_ElementNumberOfChannels = (int)mF->value[0];
1103 }
1104
1105 mF = MET_GetFieldRecord("ElementType", &m_Fields);
1106 if(mF && mF->defined)
1107 {
1108 MET_StringToType((char *)(mF->value), &m_ElementType);
1109 }
1110
1111 mF = MET_GetFieldRecord("ElementDataFile", &m_Fields);
1112 if(mF && mF->defined)
1113 {
1114 strcpy(m_ElementDataFileName, (char *)(mF->value));
1115 }
1116
1117 return true;
1118 }
1119
1120 //
1121 //
1122 //
1123 bool MetaArray::
M_ReadElements(METAIO_STREAM::ifstream * _fstream,void * _data,int _dataQuantity)1124 M_ReadElements(METAIO_STREAM::ifstream * _fstream, void * _data,
1125 int _dataQuantity)
1126 {
1127 if(META_DEBUG)
1128 {
1129 METAIO_STREAM::cout << "MetaArray: M_ReadElements" << METAIO_STREAM::endl;
1130 }
1131
1132 int elementSize;
1133 MET_SizeOfType(m_ElementType, &elementSize);
1134 int readSize = _dataQuantity*m_ElementNumberOfChannels*elementSize;
1135 if(META_DEBUG)
1136 {
1137 METAIO_STREAM::cout << "MetaArray: M_ReadElements: ReadSize = "
1138 << readSize << METAIO_STREAM::endl;
1139 }
1140
1141 // If compressed we inflate
1142 if(m_CompressedData)
1143 {
1144 // if m_CompressedElementDataSize is not defined we assume the size of the
1145 // file is the size of the compressed data
1146 if(m_CompressedElementDataSize==0)
1147 {
1148 _fstream->seekg(0, METAIO_STREAM::ios::end);
1149 m_CompressedElementDataSize = _fstream->tellg();
1150 _fstream->seekg(0, METAIO_STREAM::ios::beg);
1151 }
1152
1153 unsigned char* compr = new unsigned char[m_CompressedElementDataSize];
1154 _fstream->read((char *)compr, (size_t)m_CompressedElementDataSize);
1155
1156 MET_PerformUncompression(compr, m_CompressedElementDataSize,
1157 (unsigned char *)_data, readSize);
1158 }
1159 else // if not compressed
1160 {
1161 if(!m_BinaryData)
1162 {
1163 double tf;
1164 for(int i=0; i<_dataQuantity*m_ElementNumberOfChannels; i++)
1165 {
1166 *_fstream >> tf;
1167 MET_DoubleToValue(tf, m_ElementType, _data, i);
1168 _fstream->get();
1169 }
1170 }
1171 else
1172 {
1173 _fstream->read((char *)_data, readSize);
1174 int gc = _fstream->gcount();
1175 if(gc != readSize)
1176 {
1177 METAIO_STREAM::cout
1178 << "MetaArray: M_ReadElements: data not read completely"
1179 << METAIO_STREAM::endl;
1180 METAIO_STREAM::cout << " ideal = " << readSize
1181 << " : actual = " << gc
1182 << METAIO_STREAM::endl;
1183 return false;
1184 }
1185 }
1186 }
1187
1188 return true;
1189 }
1190
1191 //
1192 //
1193 //
1194 bool MetaArray::
M_WriteElements(METAIO_STREAM::ofstream * _fstream,const void * _data,METAIO_STL::streamoff _dataQuantity)1195 M_WriteElements(METAIO_STREAM::ofstream * _fstream, const void * _data,
1196 METAIO_STL::streamoff _dataQuantity)
1197 {
1198 bool localData = false;
1199 METAIO_STREAM::ofstream* tmpWriteStream;
1200 if(!strcmp(m_ElementDataFileName, "LOCAL"))
1201 {
1202 localData = true;
1203 tmpWriteStream = _fstream;
1204 }
1205 else
1206 {
1207 localData = false;
1208 tmpWriteStream = new METAIO_STREAM::ofstream;
1209
1210 char dataFileName[255];
1211 char pathName[255];
1212 bool usePath = MET_GetFilePath(m_FileName, pathName);
1213 if(usePath)
1214 {
1215 sprintf(dataFileName, "%s%s", pathName, m_ElementDataFileName);
1216 }
1217 else
1218 {
1219 strcpy(dataFileName, m_ElementDataFileName);
1220 }
1221
1222 // Some older sgi compilers have a error in the ofstream constructor
1223 // that requires a file to exist for output
1224 #ifdef __sgi
1225 {
1226 METAIO_STREAM::ofstream tFile(dataFileName, METAIO_STREAM::ios::out);
1227 tFile.close();
1228 }
1229 tmpWriteStream->open(dataFileName, METAIO_STREAM::ios::out);
1230 #else
1231 tmpWriteStream->open(dataFileName, METAIO_STREAM::ios::binary |
1232 METAIO_STREAM::ios::out);
1233 #endif
1234 }
1235
1236 if(!m_BinaryData)
1237 {
1238 double tf;
1239 for(int i=0; i<m_Length*m_ElementNumberOfChannels; i++)
1240 {
1241 MET_ValueToDouble(m_ElementType, _data, i, &tf);
1242 if((i+1)/10 == (double)(i+1.0)/10.0)
1243 {
1244 (*tmpWriteStream) << tf << METAIO_STREAM::endl;
1245 }
1246 else
1247 {
1248 (*tmpWriteStream) << tf << " ";
1249 }
1250 }
1251 }
1252 else
1253 {
1254 tmpWriteStream->write( (const char *)_data, (size_t)_dataQuantity );
1255 }
1256
1257 if(!localData)
1258 {
1259 tmpWriteStream->close();
1260 delete tmpWriteStream;
1261 }
1262
1263 return true;
1264 }
1265
1266
1267 #if (METAIO_USE_NAMESPACE)
1268 };
1269 #endif
1270
1271