/*============================================================================ MetaIO Copyright 2000-2010 Insight Software Consortium Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ #include "metaArray.h" #ifdef _MSC_VER #pragma warning(disable:4702) #pragma warning(disable:4996) #endif #include #include #include #include // for memcpy #include #if (METAIO_USE_NAMESPACE) namespace METAIO_NAMESPACE { #endif // // MetaArray Constructors // MetaArray:: MetaArray() :MetaForm() { if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray()" << METAIO_STREAM::endl; } m_ElementData = NULL; m_AutoFreeElementData = false; m_CompressedElementDataSize = 0; strcpy(m_ElementDataFileName, ""); MetaArray::Clear(); } // MetaArray:: MetaArray(const char *_headerName) :MetaForm() { if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray()" << METAIO_STREAM::endl; } m_ElementData = NULL; m_AutoFreeElementData = false; m_CompressedElementDataSize = 0; strcpy(m_ElementDataFileName, ""); MetaArray::Clear(); MetaArray::Read(_headerName); } // MetaArray:: MetaArray(MetaArray *_vector, bool _allocateElementData, bool _autoFreeElementData) :MetaForm() { if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray()" << METAIO_STREAM::endl; } m_ElementData = NULL; m_AutoFreeElementData = false; m_CompressedElementDataSize = 0; strcpy(m_ElementDataFileName, ""); MetaArray::Clear(); InitializeEssential(_vector->Length(), _vector->ElementType(), _vector->ElementNumberOfChannels(), _vector->ElementData(), _allocateElementData, _autoFreeElementData); CopyInfo(_vector); } // MetaArray:: MetaArray(int _length, MET_ValueEnumType _elementType, int _elementNumberOfChannels, void *_elementData, bool _allocateElementData, bool _autoFreeElementData) :MetaForm() { if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray()" << METAIO_STREAM::endl; } m_ElementData = NULL; m_AutoFreeElementData = false; m_CompressedElementDataSize = 0; strcpy(m_ElementDataFileName, ""); MetaArray::Clear(); InitializeEssential(_length, _elementType, _elementNumberOfChannels, _elementData, _allocateElementData, _autoFreeElementData); } // MetaArray:: ~MetaArray() { M_Destroy(); } // void MetaArray:: PrintInfo() const { MetaForm::PrintInfo(); METAIO_STREAM::cout << "Length = " << (int)m_Length << METAIO_STREAM::endl; METAIO_STREAM::cout << "BinaryData = " << ((m_BinaryData)?"True":"False") << METAIO_STREAM::endl; METAIO_STREAM::cout << "BinaryDataByteOrderMSB = " << ((m_BinaryDataByteOrderMSB)?"True":"False") << METAIO_STREAM::endl; char str[255]; MET_TypeToString(m_ElementType, str); METAIO_STREAM::cout << "ElementType = " << str << METAIO_STREAM::endl; METAIO_STREAM::cout << "ElementNumberOfChannels = " << m_ElementNumberOfChannels << METAIO_STREAM::endl; METAIO_STREAM::cout << "AutoFreeElementData = " << ((m_AutoFreeElementData)?"True":"False") << METAIO_STREAM::endl; METAIO_STREAM::cout << "CompressedElementDataSize = " << m_CompressedElementDataSize << METAIO_STREAM::endl; METAIO_STREAM::cout << "ElementDataFileName = " << m_ElementDataFileName << METAIO_STREAM::endl; METAIO_STREAM::cout << "ElementData = " << ((m_ElementData==NULL)?"NULL":"Valid") << METAIO_STREAM::endl; } void MetaArray:: CopyInfo(const MetaForm * _form) { MetaForm::CopyInfo(_form); } void MetaArray:: Clear(void) { if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray: Clear" << METAIO_STREAM::endl; } m_Length = 0; m_ElementType = MET_NONE; m_ElementNumberOfChannels = 1; m_CompressedElementDataSize = 0; strcpy(m_ElementDataFileName, ""); if(m_AutoFreeElementData) { if(m_ElementData != NULL) { delete [] (char *)m_ElementData; } } m_ElementData = NULL; m_AutoFreeElementData = true; MetaForm::Clear(); } bool MetaArray:: InitializeEssential(int _length, MET_ValueEnumType _elementType, int _elementNumberOfChannels, void * _elementData, bool _allocateElementData, bool _autoFreeElementData) { if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray: Initialize" << METAIO_STREAM::endl; } MetaForm::InitializeEssential(); bool result = true; if(m_Length != _length || m_ElementType != _elementType || m_ElementNumberOfChannels != _elementNumberOfChannels || _elementData != NULL || _allocateElementData == true) { if(m_AutoFreeElementData) { if(m_ElementData != NULL) { delete [] (char *)m_ElementData; } } m_ElementData = NULL; m_Length = _length; m_ElementType = _elementType; m_ElementNumberOfChannels = _elementNumberOfChannels; if(_elementData != NULL) { m_ElementData = (void *)_elementData; } else { if(_allocateElementData) { result = AllocateElementData(_autoFreeElementData); } else { m_ElementData = NULL; } } m_AutoFreeElementData = _autoFreeElementData; } return result; } bool MetaArray:: AllocateElementData(bool _autoFreeElementData) { if(m_AutoFreeElementData) { if(m_ElementData != NULL) { delete [] (char *)m_ElementData; } } m_ElementData = NULL; m_AutoFreeElementData = _autoFreeElementData; int eSize; MET_SizeOfType(m_ElementType, &eSize); m_ElementData = new char[m_Length*m_ElementNumberOfChannels*eSize]; if(m_ElementData != NULL) { return true; } else { return false; } } int MetaArray:: Length(void) const { return m_Length; } void MetaArray:: Length(int _length) { if(m_Length != _length) { InitializeEssential(_length, m_ElementType, m_ElementNumberOfChannels); } } int MetaArray:: NDims(void) const { return Length(); } void MetaArray:: NDims(int _length) { Length(_length); } MET_ValueEnumType MetaArray:: ElementType(void) const { return m_ElementType; } void MetaArray:: ElementType(MET_ValueEnumType _elementType) { if(m_ElementType != _elementType) { InitializeEssential(m_Length, _elementType, m_ElementNumberOfChannels); } } int MetaArray:: ElementNumberOfChannels(void) const { return m_ElementNumberOfChannels; } void MetaArray:: ElementNumberOfChannels(int _elementNumberOfChannels) { if(m_ElementNumberOfChannels != _elementNumberOfChannels) { InitializeEssential(m_Length, m_ElementType, _elementNumberOfChannels); } } void MetaArray:: ElementByteOrderSwap(void) { if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray: ElementByteOrderSwap" << METAIO_STREAM::endl; } int eSize; MET_SizeOfType(m_ElementType, &eSize); switch(eSize) { default: case 0: case 1: { break; } case 2: { int i; for(i=0; i _fromMax) { _fromMax = tf; } } } if(_toMin == 0 && _toMax == 0) { _toMin = _fromMin; _toMax = _fromMax; } for(int i=0; iis_open() ) { return false; } bool result = !strncmp(MET_ReadForm(inputStream).c_str(), "Array", 5); inputStream.close(); return result; } bool MetaArray:: Read(const char *_headerName, bool _readElements, void * _elementDataBuffer, bool _autoFreeElementData) { if(_headerName != NULL) { strcpy(m_FileName, _headerName); } METAIO_STREAM::ifstream * tmpStream = new METAIO_STREAM::ifstream; #ifdef __sgi tmpStream->open(m_FileName, METAIO_STREAM::ios::in ); #else tmpStream->open(m_FileName, METAIO_STREAM::ios::in | METAIO_STREAM::ios::binary); #endif if(!tmpStream->rdbuf()->is_open()) { METAIO_STREAM::cout << "MetaArray: Read: Cannot open file _" << m_FileName << "_" << METAIO_STREAM::endl; delete tmpStream; return false; } bool result = ReadStream(tmpStream, _readElements, _elementDataBuffer, _autoFreeElementData); if(_headerName != NULL) { strcpy(m_FileName, _headerName); } tmpStream->close(); delete tmpStream; return result; } bool MetaArray:: CanReadStream(METAIO_STREAM::ifstream * _stream) const { if(!strncmp(MET_ReadForm(*_stream).c_str(), "Array", 5)) { return true; } return false; } bool MetaArray:: ReadStream(METAIO_STREAM::ifstream * _stream, bool _readElements, void * _elementDataBuffer, bool _autoFreeElementData) { if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray: ReadStream" << METAIO_STREAM::endl; } M_Destroy(); Clear(); M_SetupReadFields(); if(m_ReadStream) { METAIO_STREAM::cout << "MetaArray: ReadStream: two files open?" << METAIO_STREAM::endl; delete m_ReadStream; } m_ReadStream = _stream; if(!M_Read()) { METAIO_STREAM::cout << "MetaArray: Read: Cannot parse file" << METAIO_STREAM::endl; m_ReadStream = NULL; return false; } InitializeEssential(m_Length, m_ElementType, m_ElementNumberOfChannels, _elementDataBuffer, true, _autoFreeElementData); bool usePath; char pathName[255]; char fName[255]; usePath = MET_GetFilePath(m_FileName, pathName); if(_readElements) { if(!strcmp("Local", m_ElementDataFileName) || !strcmp("LOCAL", m_ElementDataFileName) || !strcmp("local", m_ElementDataFileName)) { M_ReadElements(m_ReadStream, m_ElementData, m_Length); } else { if(usePath) { sprintf(fName, "%s%s", pathName, m_ElementDataFileName); } else { strcpy(fName, m_ElementDataFileName); } METAIO_STREAM::ifstream* readStreamTemp = new METAIO_STREAM::ifstream; #ifdef __sgi readStreamTemp->open(fName, METAIO_STREAM::ios::in); #else readStreamTemp->open(fName, METAIO_STREAM::ios::binary | METAIO_STREAM::ios::in); #endif if(!readStreamTemp->rdbuf()->is_open()) { METAIO_STREAM::cout << "MetaArray: Read: Cannot open data file" << METAIO_STREAM::endl; m_ReadStream = NULL; return false; } if(_readElements) { M_ReadElements(readStreamTemp, m_ElementData, m_Length); } readStreamTemp->close(); delete readStreamTemp; } } m_ReadStream = NULL; return true; } // // // // bool MetaArray:: Write(const char *_headName, const char *_dataName, bool _writeElements, const void *_constElementData) { if(_headName != NULL && strlen(_headName)>1) { FileName(_headName); } bool tmpDataFileName = false; if( _dataName != NULL && strlen(_dataName) > 1 ) { tmpDataFileName = true; ElementDataFileName(_dataName); } else { if( strlen(m_ElementDataFileName) == 0 ) { tmpDataFileName = true; } } int sPtr = 0; MET_GetFileSuffixPtr(m_FileName, &sPtr); if( !strcmp(&(m_FileName[sPtr]), "mvh") ) { MET_SetFileSuffix(m_FileName, "mvh"); if( strlen(m_ElementDataFileName) == 0 || !strcmp(m_ElementDataFileName, "LOCAL") ) { ElementDataFileName(m_FileName); } if(m_CompressedData) { MET_SetFileSuffix(m_ElementDataFileName, "zmvd"); } else { MET_SetFileSuffix(m_ElementDataFileName, "mvd"); } } else { MET_SetFileSuffix(m_FileName, "mva"); ElementDataFileName("LOCAL"); } char pathName[255]; bool usePath = MET_GetFilePath(m_FileName, pathName); if(usePath) { char elementPathName[255]; MET_GetFilePath(m_ElementDataFileName, elementPathName); if(!strcmp(pathName, elementPathName)) { strcpy(elementPathName, &m_ElementDataFileName[strlen(pathName)]); strcpy(m_ElementDataFileName, elementPathName); } } METAIO_STREAM::ofstream * tmpWriteStream = new METAIO_STREAM::ofstream; // Some older sgi compilers have a error in the ofstream constructor // that requires a file to exist for output #ifdef __sgi { METAIO_STREAM::ofstream tFile(m_FileName, METAIO_STREAM::ios::out); tFile.close(); } tmpWriteStream->open(m_FileName, METAIO_STREAM::ios::out); #else tmpWriteStream->open(m_FileName, METAIO_STREAM::ios::binary | METAIO_STREAM::ios::out); #endif if(!tmpWriteStream->rdbuf()->is_open()) { if(tmpDataFileName) { ElementDataFileName(""); } delete tmpWriteStream; return false; } bool result = WriteStream(tmpWriteStream, _writeElements, _constElementData); if(tmpDataFileName) { ElementDataFileName(""); } tmpWriteStream->close(); delete tmpWriteStream; return result; } bool MetaArray:: WriteStream(METAIO_STREAM::ofstream * _stream, bool _writeElements, const void *_constElementData) { if(m_WriteStream != NULL) { METAIO_STREAM::cout << "MetaArray: WriteStream: two files open?" << METAIO_STREAM::endl; delete m_WriteStream; } m_WriteStream = _stream; unsigned char * compressedElementData = NULL; if(m_CompressedData) { int elementSize; MET_SizeOfType(m_ElementType, &elementSize); int elementNumberOfBytes = elementSize*m_ElementNumberOfChannels; if(_constElementData == NULL) { compressedElementData = MET_PerformCompression( (const unsigned char *)m_ElementData, m_Length * elementNumberOfBytes, & m_CompressedElementDataSize); } else { compressedElementData = MET_PerformCompression( (const unsigned char *)_constElementData, m_Length * elementNumberOfBytes, & m_CompressedElementDataSize); } } M_SetupWriteFields(); M_Write(); if(_writeElements) { if(m_CompressedData) { M_WriteElements(m_WriteStream, compressedElementData, m_CompressedElementDataSize); delete [] compressedElementData; } else { int elementSize; MET_SizeOfType(m_ElementType, &elementSize); int elementNumberOfBytes = elementSize*m_ElementNumberOfChannels; if(_constElementData != NULL) { M_WriteElements(m_WriteStream, _constElementData, elementNumberOfBytes * m_Length); } else { M_WriteElements(m_WriteStream, m_ElementData, elementNumberOfBytes * m_Length); } } } m_WriteStream->flush(); m_WriteStream = NULL; return true; } void MetaArray:: M_Destroy(void) { if(m_AutoFreeElementData && m_ElementData != NULL) { delete [] (char *)m_ElementData; } m_ElementData = NULL; MetaForm::M_Destroy(); } void MetaArray:: M_SetupReadFields(void) { if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray: M_SetupReadFields" << METAIO_STREAM::endl; } MetaForm::M_SetupReadFields(); MET_FieldRecordType * mF; mF = new MET_FieldRecordType; MET_InitReadField(mF, "Length", MET_INT, false); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "NDims", MET_INT, false); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "ElementNumberOfChannels", MET_INT, false); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "ElementType", MET_STRING, true); mF->required = true; m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "ElementDataFile", MET_STRING, true); mF->required = true; mF->terminateRead = true; m_Fields.push_back(mF); } void MetaArray:: M_SetupWriteFields(void) { strcpy(m_FormTypeName, "Array"); MetaForm::M_SetupWriteFields(); MET_FieldRecordType * mF; mF = new MET_FieldRecordType; MET_InitWriteField(mF, "Length", MET_INT, m_Length); m_Fields.push_back(mF); if(m_ElementNumberOfChannels>1) { mF = new MET_FieldRecordType; MET_InitWriteField(mF, "ElementNumberOfChannels", MET_INT, m_ElementNumberOfChannels); m_Fields.push_back(mF); } char s[80]; mF = new MET_FieldRecordType; MET_TypeToString(m_ElementType, s); MET_InitWriteField(mF, "ElementType", MET_STRING, strlen(s), s); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitWriteField(mF, "ElementDataFile", MET_STRING, strlen(m_ElementDataFileName), m_ElementDataFileName); mF->terminateRead = true; m_Fields.push_back(mF); } bool MetaArray:: M_Read(void) { if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray: M_Read: Loading Header" << METAIO_STREAM::endl; } if(!MetaForm::M_Read()) { METAIO_STREAM::cout << "MetaArray: M_Read: Error parsing file" << METAIO_STREAM::endl; return false; } if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray: M_Read: Parsing Header" << METAIO_STREAM::endl; } MET_FieldRecordType * mF; mF = MET_GetFieldRecord("Length", &m_Fields); if(mF && mF->defined) { m_Length = (int)mF->value[0]; } else { mF = MET_GetFieldRecord("NDims", &m_Fields); if(mF && mF->defined) { m_Length = (int)mF->value[0]; } else { METAIO_STREAM::cout << "MetaArray: M_Read: Error: Length required" << METAIO_STREAM::endl; return false; } } mF = MET_GetFieldRecord("ElementNumberOfChannels", &m_Fields); if(mF && mF->defined) { m_ElementNumberOfChannels = (int)mF->value[0]; } mF = MET_GetFieldRecord("ElementType", &m_Fields); if(mF && mF->defined) { MET_StringToType((char *)(mF->value), &m_ElementType); } mF = MET_GetFieldRecord("ElementDataFile", &m_Fields); if(mF && mF->defined) { strcpy(m_ElementDataFileName, (char *)(mF->value)); } return true; } // // // bool MetaArray:: M_ReadElements(METAIO_STREAM::ifstream * _fstream, void * _data, int _dataQuantity) { if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray: M_ReadElements" << METAIO_STREAM::endl; } int elementSize; MET_SizeOfType(m_ElementType, &elementSize); int readSize = _dataQuantity*m_ElementNumberOfChannels*elementSize; if(META_DEBUG) { METAIO_STREAM::cout << "MetaArray: M_ReadElements: ReadSize = " << readSize << METAIO_STREAM::endl; } // If compressed we inflate if(m_CompressedData) { // if m_CompressedElementDataSize is not defined we assume the size of the // file is the size of the compressed data if(m_CompressedElementDataSize==0) { _fstream->seekg(0, METAIO_STREAM::ios::end); m_CompressedElementDataSize = _fstream->tellg(); _fstream->seekg(0, METAIO_STREAM::ios::beg); } unsigned char* compr = new unsigned char[static_cast(m_CompressedElementDataSize)]; _fstream->read((char *)compr, (size_t)m_CompressedElementDataSize); MET_PerformUncompression(compr, m_CompressedElementDataSize, (unsigned char *)_data, readSize); } else // if not compressed { if(!m_BinaryData) { double tf; for(int i=0; i<_dataQuantity*m_ElementNumberOfChannels; i++) { *_fstream >> tf; MET_DoubleToValue(tf, m_ElementType, _data, i); _fstream->get(); } } else { _fstream->read((char *)_data, readSize); int gc = static_cast(_fstream->gcount()); if(gc != readSize) { METAIO_STREAM::cout << "MetaArray: M_ReadElements: data not read completely" << METAIO_STREAM::endl; METAIO_STREAM::cout << " ideal = " << readSize << " : actual = " << gc << METAIO_STREAM::endl; return false; } } } return true; } // // // bool MetaArray:: M_WriteElements(METAIO_STREAM::ofstream * _fstream, const void * _data, METAIO_STL::streamoff _dataQuantity) { bool localData = false; METAIO_STREAM::ofstream* tmpWriteStream; if(!strcmp(m_ElementDataFileName, "LOCAL")) { localData = true; tmpWriteStream = _fstream; } else { localData = false; tmpWriteStream = new METAIO_STREAM::ofstream; char dataFileName[255]; char pathName[255]; bool usePath = MET_GetFilePath(m_FileName, pathName); if(usePath) { sprintf(dataFileName, "%s%s", pathName, m_ElementDataFileName); } else { strcpy(dataFileName, m_ElementDataFileName); } // Some older sgi compilers have a error in the ofstream constructor // that requires a file to exist for output #ifdef __sgi { METAIO_STREAM::ofstream tFile(dataFileName, METAIO_STREAM::ios::out); tFile.close(); } tmpWriteStream->open(dataFileName, METAIO_STREAM::ios::out); #else tmpWriteStream->open(dataFileName, METAIO_STREAM::ios::binary | METAIO_STREAM::ios::out); #endif } if(!m_BinaryData) { double tf; for(int i=0; iwrite( (const char *)_data, (size_t)_dataQuantity ); } if(!localData) { tmpWriteStream->close(); delete tmpWriteStream; } return true; } #if (METAIO_USE_NAMESPACE) }; #endif