📄 cmatfile.h
字号:
/*------------------------------------------------------------------------------*
* File Name: CMATFile.h *
* Creation: Soapy *
* Purpose: CMATFile class for MAT file import *
* Copyright (c) ABCD Corp. 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 *
* All Rights Reserved *
* *
* Modification Log: *
*------------------------------------------------------------------------------*/
#ifndef _CMATFILE_H
#define _CMATFILE_H
#include <origin.h>
#include <OArrayBase.h>
#define MAX_VAR_NAME_SIZE 32 // maximum length of MAT file name
#define SUPPORT_DIMESION 2 // Currently, Origin only support array of 1 or 2 dimension
#define DATA_BOUNDARY_IN_BYTE 8 // Data Elements in MAT file are align to 8 byte boundary
enum MATArrayClass{
MAT_ARRAY_mxCELL_CLASS = 1, // Not support currently
MAT_ARRAY_mxSTRUCTURE_CLASS = 2,// Not support currently
MAT_ARRAY_mxOBJECT_CLASS = 3, // Not support currently
MAT_ARRAY_mxCHARACTER_CLASS = 4,
MAT_ARRAY_mxSPARSE_CLASS = 5,
MAT_ARRAY_mxDOUBLE_CLASS = 6,
MAT_ARRAY_mxSINGLE_CLASS = 7,
MAT_ARRAY_mxINT8_CLASS = 8,
MAT_ARRAY_mxUINT8_CLASS = 9,
MAT_ARRAY_mxINT16_CLASS = 10,
MAT_ARRAY_mxUINT16_CLASS = 11,
MAT_ARRAY_mxINT32_CLASS = 12,
MAT_ARRAY_mxUINT32_CLASS = 13,
MAT_ARRAY_mxCOMPLEX_CLASS = 14
};
enum MATDataType{
MAT_DataType_miINT8 = 1,
MAT_DataType_miUINT8 = 2,
MAT_DataType_miINT16 = 3,
MAT_DataType_miUINT16 = 4,
MAT_DataType_miINT32 = 5,
MAT_DataType_miUINT32 = 6,
MAT_DataType_miSINGLE = 7,
MAT_DataType_miReserved1 = 8,
MAT_DataType_miDOUBLE = 9,
MAT_DataType_miReserved2 = 10,
MAT_DataType_miReserved3 = 11,
MAT_DataType_miINT64 = 12, // Not support currently
MAT_DataType_miUINT64 = 13, // Not support currently
MAT_DataType_miMATRIX = 14
};
class CElementBase : public OObject
{
public:
CElementBase(bool bIsLittleEndian, file *pfMATFile)
{
Init(bIsLittleEndian, pfMATFile);
}
~CElementBase()
{
}
private:
void Init(bool bIsLittleEndian, file *pfMATFile)
{
m_bIsLittleEndian = bIsLittleEndian;
m_pfMATFile = pfMATFile;
}
public:
virtual BOOL ReadTag() // Read the tag of the data element
{
if(!m_pfMATFile->IsOpen())
return false;
m_lPosition = m_pfMATFile->GetPosition();
unsigned int iTemp;
if(1!=m_pfMATFile->ReadInt(&iTemp, sizeof(int), 1, m_bIsLittleEndian))
return false;
if ( iTemp > 0x10000 ) // Is the data stored in a compressed form?
{
m_dwSize = iTemp / 0x10000;
m_dwDataTye = mod(iTemp, 0x10000);
}
else
{
m_dwDataTye = iTemp;
if(1!=m_pfMATFile->ReadInt(&m_dwSize, sizeof(int), 1, m_bIsLittleEndian))
return false;
}
return TRUE;
}
BOOL SkipRemainBytes() // Skip the remain bytes to align to the 8 byte boundary
{
if(m_pfMATFile->IsOpen())
{
LONG lOffset;
if( 0 != mod(m_dwSize, DATA_BOUNDARY_IN_BYTE))
{
if( m_dwSize <= sizeof(int))
lOffset = DATA_BOUNDARY_IN_BYTE;
else
lOffset = (m_dwSize/DATA_BOUNDARY_IN_BYTE+2)*DATA_BOUNDARY_IN_BYTE;
}
else
{
lOffset = m_dwSize+DATA_BOUNDARY_IN_BYTE;
}
m_pfMATFile->Seek(lOffset+m_lPosition, file::begin);
return true;
}
return false;
}
public:
LONG m_lPosition; // the position of the data element in the file
unsigned int m_dwSize; // the size of the data element
unsigned int m_dwDataTye; // the data type
BOOL m_bIsLittleEndian; // Big_Endian or Little_Endian
file* m_pfMATFile; // the file pointer
};
// The Array_Flag Sub_element
class CArrayFlagEle : public CElementBase
{
public:
CArrayFlagEle(bool bIsLittleEndian, file *pfMATFile) : CElementBase(bIsLittleEndian,pfMATFile)
{
}
BOOL GetData(bool& bIsComplex, uint& bClassType)
{
if ( !ReadTag() )
return FALSE;
int bArrayFlag[2];
if( 2 != m_pfMATFile->ReadInt(&bArrayFlag, sizeof(int), 2, m_bIsLittleEndian))
return false;
bIsComplex = (bArrayFlag[0] & 0x0800)/ 0x100;
bClassType = bArrayFlag[0] & 0xFF;
return true;
}
};
// The Dimension Sub_element
class CDimensionEle : public CElementBase
{
public:
CDimensionEle(bool bIsLittleEndian, file *pfMATFile) : CElementBase(bIsLittleEndian,pfMATFile)
{
}
BOOL GetData(vector<uint>& vecDimension)
{
if ( !ReadTag() )
return FALSE;
uint nDimensionSize = m_dwSize / sizeof(int);
vecDimension.SetSize(nDimensionSize);
uint nRet = m_pfMATFile->ReadInt(&vecDimension, sizeof(int), nDimensionSize, m_bIsLittleEndian);
if(nRet != nDimensionSize)
return false;
SkipRemainBytes();
return true;
}
};
// The Array Name Sub_element
class CArrayNameEle : public CElementBase
{
public:
CArrayNameEle(bool bIsLittleEndian, file *pfMATFile) : CElementBase(bIsLittleEndian,pfMATFile)
{
}
BOOL GetData(string& strArrayName)
{
if ( !ReadTag() )
return FALSE;
char strName[MAX_VAR_NAME_SIZE]; ///Soapy 08/21/03 QA70-3572 v7.0664 CODE_UPDATE_FOR_IMPOTR_MAT_FILE_2
if( m_dwSize != m_pfMATFile->ReadInt(strName, sizeof(char), m_dwSize, m_bIsLittleEndian))
return false;
strArrayName = strName;
SkipRemainBytes();
return true;
}
};
// The Array Data Sub_element
class CArrayDataEle : public CElementBase
{
public:
CArrayDataEle(bool bIsLittleEndian, file *pfMATFile) : CElementBase(bIsLittleEndian,pfMATFile)
{
}
int GetData(vector& vData)
{
if ( !ReadTag() )
return FALSE;
bool bSuccess = false;
int nItem;
switch(m_dwDataTye)
{
case MAT_DataType_miINT8: // INT8
nItem = m_dwSize / sizeof(char);
vector<char> vecCh(nItem);
if(nItem == m_pfMATFile->ReadInt(&vecCh, sizeof(byte), nItem, m_bIsLittleEndian))
{
vData=vecCh;
bSuccess = true;
}
break;
case MAT_DataType_miUINT8: // Unsigned INT8
nItem = m_dwSize / sizeof(byte);
vector<byte> vecByte(nItem);
if(nItem == m_pfMATFile->ReadInt(&vecByte, sizeof(byte), nItem, m_bIsLittleEndian))
{
vData=vecByte;
bSuccess = true;
}
break;
case MAT_DataType_miINT16: // INT16
nItem = m_dwSize / sizeof(short);
vector<short> vecInt16(nItem);
if(nItem == m_pfMATFile->ReadInt(&vecInt16, sizeof(short), nItem, m_bIsLittleEndian))
{
vData=vecInt16;
bSuccess = true;
}
break;
case MAT_DataType_miUINT16: // Unsigned INT16
nItem = m_dwSize / sizeof(short);
vector<unsigned short> vecUInt16(nItem);
if(nItem == m_pfMATFile->ReadInt(&vecUInt16, sizeof(short), nItem, m_bIsLittleEndian))
{
vData=vecUInt16;
bSuccess = true;
}
break;
case MAT_DataType_miINT32: // INT32
nItem = m_dwSize / sizeof(int);
vector<int> vecInt32(nItem);
if(nItem == m_pfMATFile->ReadInt(&vecInt32, sizeof(int), nItem, m_bIsLittleEndian))
{
vData=vecInt32;
bSuccess = true;
}
break;
case MAT_DataType_miUINT32: // Unsigned INT32
nItem = m_dwSize / sizeof(int);
vector<unsigned int> vecUInt32(nItem);
if(nItem == m_pfMATFile->ReadInt(&vecUInt32, sizeof(int), nItem, m_bIsLittleEndian))
{
vData=vecUInt32;
bSuccess = true;
}
break;
case MAT_DataType_miSINGLE: // Single Format
nItem = m_dwSize / sizeof(float);
vector<float> vecFloat(nItem);
if(nItem == m_pfMATFile->ReadFloat(&vecFloat, sizeof(float), nItem, m_bIsLittleEndian))
{
vData=vecFloat;
bSuccess = true;
}
break;
case MAT_DataType_miDOUBLE: // Double Format
nItem = m_dwSize / sizeof(double);
vData.SetSize(nItem);
if(nItem == m_pfMATFile->ReadFloat(&vData, sizeof(double), nItem, m_bIsLittleEndian))
{
//vecTemp=vecFloat;
bSuccess = true;
}
break;
case MAT_DataType_miINT64: // INT64 -- Not Support Now
case MAT_DataType_miUINT64: // Unsigned INT64 -- Not Support Now
return 0;
break;
default: return -1;// 8, 10, 11 Are Reserved
}
if(bSuccess)
{
SkipRemainBytes();
return 1;
}
return -1;
}
};
// The Array Element Which Contains Particular Sub_elements
class CDataElement : public CElementBase
{
public:
CDataElement(bool bIsLittleEndian, file *pfMATFile) : CElementBase(bIsLittleEndian,pfMATFile)
{
Reset();
}
BOOL ReadTag()
{
if(!CElementBase::ReadTag())
return false;
if(m_dwDataTye != MAT_DataType_miMATRIX)
return false;
return TRUE;
}
BOOL GetData()
{
if ( !ReadTag() )
return FALSE;
if(!ReadSubElement())
{
Reset();
return false;
}
return true;
}
private:
void Reset();
bool ReadSubElement();
int ReadRegularArray(bool bIsComplex);
int ReadSparseArray(bool bIsComplex);
public:
string m_strVarName; // Variable Name
vector<uint> m_vDimesion; // The size of each dimension
bool m_bImportable; // Origin import support or not
vector m_vReal; // The real part of the data
vector m_vImaginary;
};
void CDataElement::Reset()
{
m_bImportable = false;
m_vDimesion.SetSize(0);
m_vReal.SetSize(0);
m_vImaginary.SetSize(0);
}
bool CDataElement::ReadSubElement()
{
bool bIsComplex;
// Read the Array_Flag
CArrayFlagEle ArrayFlag(m_bIsLittleEndian, m_pfMATFile);
if(!ArrayFlag.GetData(bIsComplex, m_dwDataTye))
return false;
// Read the Dimension Array
CDimensionEle DimensionArray(m_bIsLittleEndian, m_pfMATFile);
if(!DimensionArray.GetData(m_vDimesion))
return false;
// Read the Array Name
CArrayNameEle ArrayName(m_bIsLittleEndian, m_pfMATFile);
if(!ArrayName.GetData(m_strVarName))
return false;
// Skip the remain bytes of this data element if it's not supported by Origin
if(( m_dwDataTye < MAT_ARRAY_mxCHARACTER_CLASS) ||
(m_vDimesion.GetSize() > SUPPORT_DIMESION))
{
SkipRemainBytes();
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -