⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmatfile.h

📁 图像处理的压缩算法
💻 H
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------------*
 * 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 + -