📄 cmatfile.h
字号:
// Read the Array Data
int nRet;
if( MAT_ARRAY_mxSPARSE_CLASS != m_dwDataTye) //regular array
{
nRet = ReadRegularArray(bIsComplex);
}
else
{
nRet = ReadSparseArray(bIsComplex);
}
// Skip the remain bytes
if(nRet>=0)
{
SkipRemainBytes();
if(nRet == 1)
m_bImportable = true;
return true;
}
return false;
}
// Read the regular Array
int CDataElement::ReadRegularArray(bool bIsComplex)
{
int nRet;
CArrayDataEle ArrayData(m_bIsLittleEndian, m_pfMATFile);
nRet = ArrayData.GetData(m_vReal);
if(nRet <= 0)
return nRet;
if(bIsComplex)
{
m_dwDataTye = MAT_ARRAY_mxCOMPLEX_CLASS;
nRet = ArrayData.GetData(m_vImaginary);
if(nRet <= 0)
return nRet;
}
return 1;
}
// Read the Sparse Array which is stored in a packed form
int CDataElement::ReadSparseArray(bool bIsComplex)
{
int nRet;
// Get the row index and column index of the non-zero array element
vector<uint> vDimRows, vDimCols;
CDimensionEle NonZDim(m_bIsLittleEndian, m_pfMATFile);
if(!NonZDim.GetData(vDimRows))
return -1;
if(!NonZDim.GetData(vDimCols))
return -1;
int nNonZero = vDimRows.GetSize();
vDimCols.SetSize(nNonZero);
// Calculate the size of the array
int nSize = m_vDimesion[0] * m_vDimesion[1];
m_vReal.SetSize(nSize);
m_vImaginary.SetSize(nSize);
// Calculate the offset of each non-zero array element
int nRows = m_vDimesion[0];
vector<uint> vIndex(nNonZero);
vIndex = vDimRows + vDimCols * nRows;
// Get the values of the non-zero array element
vector vReal, vImaginary;
CArrayDataEle ArrayData(m_bIsLittleEndian, m_pfMATFile);
nRet = ArrayData.GetData(vReal);
if(nRet <= 0)
return nRet;
// Assign the value to the Data Element
for(int i=0; i<nNonZero; i++)
{
uint nIndex = vDimRows[i]+vDimCols[i]*m_vDimesion[0];
m_vReal[vIndex[i]] = vReal[i];
}
// Read the imaginary part
if(bIsComplex)
{
m_dwDataTye = MAT_ARRAY_mxCOMPLEX_CLASS;
nRet = ArrayData.GetData(vImaginary);
if(nRet <= 0)
return nRet;
for(i=0; i<nNonZero; i++)
{
m_vImaginary[vIndex[i]] = vImaginary[i];
}
}
else
{
m_vImaginary.SetSize(0);
}
return 1;
}
#define MAT_FILE_HEAD_SIZE 126
class CPtrDataElementArray : public OPtrArray
{
public:
~CPtrDataElementArray()
{
RemoveAll();
}
public:
void RemoveAt(int nIndex)
{
CDataElement* pDataElement = GetAt(nIndex);
NICE_REMOVE(pDataElement);
OPtrArray::RemoveAt(nIndex);
}
CDataElement* GetAt(int nIndex)
{
return (CDataElement*)OPtrArray::GetAt(nIndex);
}
int Add(CDataElement* pDataElement)
{
return OPtrArray::Add((DWORD)pDataElement);
}
void RemoveAll()
{
int nSize = OPtrArray::GetSize();
for(int i=nSize-1; i>=0; i--)
{
RemoveAt(i);
}
OPtrArray::RemoveAll();
}
};
class CMATFile
{
public:
CMATFile()
{
Init();
}
~CMATFile()
{
}
private:
void Init();
void Reset();
// Add the data info to the tree
bool SetDataInfoToTree(CDataElement* FileElement);
public:
// Read the .mat file
bool ReadMATFile(LPCSTR lpcstrFileName);
// Set the element data to matrices
bool SetMatrix(uint nIndex, matrix& mReal, matrix& mImaginary);
// Get all the data elements Origin support
bool GetAllImportable(vector<uint>& vecIndex);
// Get all the real data elements Origin support
bool GetAllRealImportable(vector<uint>& vecIndex);
void OutMatFileInfo();
private:
file m_fMATFile; // file object
bool m_bIsLittleEndian;
bool m_bReadFileStatus; // Indicate the status of the reading
CPtrDataElementArray m_Data;
public:
Tree m_trFileInfo; // the summary of the data elements in the file (for import dialog).
};
void CMATFile::Init()
{
m_bReadFileStatus = false;
}
void CMATFile::Reset()
{
Init();
if ( m_fMATFile.IsOpen() )
m_fMATFile.Close();
m_trFileInfo.Reset();
m_Data.RemoveAll();
}
// Add the data info to the tree
bool CMATFile::SetDataInfoToTree(CDataElement* FileElement)
{
// Set the TreeNode's name and ID
int nID = m_Data.GetSize();
TreeNode trNodeNew = m_trFileInfo.AddNode(FileElement->m_strVarName, nID);
// The description of array dimension
string strDim = FileElement->m_vDimesion[0];
for(int ii=1; ii<FileElement->m_vDimesion.GetSize(); ii++)
{
strDim += " x " + FileElement->m_vDimesion[ii];
}
trNodeNew.Size.strVal=strDim;
// If the data element is imported
trNodeNew.Imported.nVal = FileElement->m_bImportable;
// The description of the array type
string strType;
switch(FileElement->m_dwDataTye)
{
case MAT_ARRAY_mxINT8_CLASS:
strType = "INT8";
break;
case MAT_ARRAY_mxUINT8_CLASS:
strType = "UINT8";
break;
case MAT_ARRAY_mxINT16_CLASS:
strType = "INT16";
break;
case MAT_ARRAY_mxUINT16_CLASS:
strType = "UINT16";
break;
case MAT_ARRAY_mxINT32_CLASS:
strType = "INT32";
break;
case MAT_ARRAY_mxUINT32_CLASS:
strType = "UINT32";
break;
case MAT_ARRAY_mxSINGLE_CLASS:
strType = "SINGLE";
break;
case MAT_ARRAY_mxDOUBLE_CLASS:
strType = "DOUBLE";
break;
case MAT_ARRAY_mxCHARACTER_CLASS:
strType = "CHAR";
break;
case MAT_ARRAY_mxCOMPLEX_CLASS:
strType = "COMPLEX";
break;
case MAT_ARRAY_mxSPARSE_CLASS:
strType = "DOUBLE SPARSE";
break;
default: strType = "UNKNOWN";
break;
}
trNodeNew.Type.strVal=strType;
return true;
}
// Read the .mat file
bool CMATFile::ReadMATFile(LPCSTR lpcstrFileName)
{
Reset();
// Check the input file name
string strFileName = lpcstrFileName;
if((strFileName.GetLength() == 0) || !strFileName.IsFile() ||
!m_fMATFile.Open( strFileName, file::modeRead ) || !m_fMATFile.IsOpen())
{
return false;
}
// Check the file length
if(mod(m_fMATFile.GetLength(), DATA_BOUNDARY_IN_BYTE) != 0)
{
m_fMATFile.Close();
return false;
}
// Skip the MAT-File Header
m_fMATFile.Seek(MAT_FILE_HEAD_SIZE, file::begin);
char cTemp[2];
m_fMATFile.Read( cTemp, 2);
if(cTemp[0] == 'I' && cTemp[1] == 'M')
{
m_bIsLittleEndian = true;
}
else if(cTemp[0] == 'M' && cTemp[1] == 'I')
{
m_bIsLittleEndian = false;
}
else
{
m_fMATFile.Close();
return false;
}
// Read the Data Elements
uint nFileSize = m_fMATFile.GetLength();
while(nFileSize > m_fMATFile.GetPosition())
{
CDataElement* FileElement = new CDataElement(m_bIsLittleEndian,&m_fMATFile);
if(!FileElement->GetData())
{
Reset();
NICE_REMOVE(FileElement);
return false;
}
SetDataInfoToTree(FileElement);
m_Data.Add(FileElement);
}
m_fMATFile.Close();
m_bReadFileStatus = true;
return true;
}
/*---- The following functions should be called after the CMATFile::ReadMATFile() and
m_bReadFileStatus = true ------
*/
bool CMATFile::SetMatrix(uint nIndex, matrix& mReal, matrix& mImaginary)
{
if(!m_bReadFileStatus)
return false;
CDataElement* pDataElement = m_Data.GetAt(nIndex);
if((!pDataElement)||(!pDataElement->m_bImportable))
return false;
int nRows = pDataElement->m_vDimesion[0];
int nCols = pDataElement->m_vDimesion[1];
mReal.SetSize(nRows, nCols);
mImaginary.SetSize(nRows, nCols);
mReal.SetByVector(pDataElement->m_vReal, false);
if(pDataElement->m_dwDataTye == MAT_ARRAY_mxCOMPLEX_CLASS)
{
mImaginary.SetByVector(pDataElement->m_vImaginary, false);
}
else
{
mImaginary = 0;
}
return true;
}
// Get all the data elements Origin support
bool CMATFile::GetAllImportable(vector<uint>& vecIndex)
{
if(!m_bReadFileStatus)
return false;
vecIndex.SetSize(0);
for(int ii=0; ii<m_Data.GetSize(); ii++)
{
CDataElement* pDataElement = m_Data.GetAt(ii);
if(pDataElement->m_bImportable)
vecIndex.Add(ii);
}
return true;
}
// Get all the real data elements Origin support
bool CMATFile::GetAllRealImportable(vector<uint>& vecIndex)
{
if(!m_bReadFileStatus)
return false;
vecIndex.SetSize(0);
for(int ii=0; ii<m_Data.GetSize(); ii++)
{
CDataElement* pDataElement = m_Data.GetAt(ii);
if(pDataElement->m_bImportable && (pDataElement->m_dwDataTye != MAT_ARRAY_mxCOMPLEX_CLASS))
vecIndex.Add(ii);
}
return true;
}
void CMATFile::OutMatFileInfo()
{
out_tree(m_trFileInfo);
}
#endif //_CMATFILE_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -