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

📄 avitools.cpp

📁 超声影像工作站系统可与各种型号的B超、彩超连接
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// AVITools.cpp : implementation file
//

#include "stdafx.h"
#include "AVITools.h"

/////////////////////////////////////////////////////////////////////////////
// CAVITools

/*
	构造函数初始化环境以及数据
*/
CAVITools::CAVITools()
{
	//	初始化 AVI 库
	::AVIFileInit();

	m_strAviFileName		= _T("");		//	AVI 文件名
	m_iCurrentFrameCount	= 0;			//	当前侦
	m_iWidth				= -1;			//	侦宽度(像素)
	m_iHeight				= -1;			//	侦高度(像素)

	m_pAviFile				= NULL;			//	PAVIFILE
	m_pAviStream			= NULL;			//	PAVISTREAM
	m_pCompressedAviStream	= NULL;			//	PCOMPRESSAVISTREAM
	m_pBuffer				= NULL;			//	缓冲区
	m_pFormat				= NULL;			//	格式指针

	//	初始化结构变量
	memset(&m_AviStreamInfo, 0, sizeof(AVISTREAMINFO));
	memset(&m_AviCompressOptions, 0, sizeof(AVICOMPRESSOPTIONS));
}

/*
	析构函数清理内存,退出 AVI 库
*/
CAVITools::~CAVITools()
{
	CleanUp();
	::AVIFileExit();
}

/*
	CREATE A AVI FILE ON DISK
	ARGUMENTS:
		sFileName			-	THE PATHNAME OF AVI FILE THAT YOU WANT TO CREATE
	RETURN VALUE:
		ERR_OK				-	SUCCESS
		ERR_FORMAT_NOT_SET	-	UNKNOWN AVI STREAM FORMAT, SUCH AS PATTLE,WIDTH AND HEIGHT, ETC.
								YOU SHOULD CALL 'SetStreamFormatFromFile' OR 'SetStreamFormatFromMemory'
								IN ORDER TO SET STREAM FORMAT BEFORE YOU CALL THIS FUNCTION
		ERR_AVI_FILE_ERROR	-	POSSIBLE RESEAN:
								1. AVIFileOpen Error
								2. AVIFileCreateStream Error
								3. AVISaveOptions Error
								4. AVIMakeCompressedStream Error
								5. AVIStreamSetFormat Error
*/
HRESULT
CAVITools::CreateAviFile(CHAR *sFileName, DWORD dwRate)
{
	m_strAviFileName	= sFileName;

	HRESULT			hr;

	if	(NULL	== m_pFormat)
	{
		m_iLastErrorNumber	= ERR_FORMAT_NOT_SET;
		m_sLastErrorDescribe.Format("没有设置 AVI 流格式,例如调色板、图象大小等");
		return ERR_FORMAT_NOT_SET;
	}

	m_iWidth	= m_pFormat->biWidth;
	m_iHeight	= m_pFormat->biHeight;

	//	创建 AVI 文件
	hr	= ::AVIFileOpen(&m_pAviFile, m_strAviFileName, OF_CREATE | OF_WRITE, NULL);
	if	(AVIERR_OK	!= hr)
	//	创建文件失败
	{
		CleanUp();
		m_iLastErrorNumber	= ERR_AVI_FILE_ERROR;
		m_sLastErrorDescribe.Format("AVIFileOpen 函数出错:%ld",hr);
		return ERR_AVI_FILE_ERROR;
	}
	
	//	初始化流信息结构
	m_AviStreamInfo.fccType					= streamtypeVIDEO;
	m_AviStreamInfo.fccHandler				= 0;
	m_AviStreamInfo.dwScale					= 1;
	m_AviStreamInfo.dwRate					= dwRate;
	m_AviStreamInfo.dwSuggestedBufferSize	= m_pFormat->biSizeImage;
	::SetRect(&m_AviStreamInfo.rcFrame,	0, 0, (INT)m_pFormat->biWidth, (INT)m_pFormat->biHeight);

	//	创建 AVI 视频流
	hr	= ::AVIFileCreateStream(m_pAviFile,&m_pAviStream,&m_AviStreamInfo);
	if	(AVIERR_OK	!= hr)
	//	创建视频流失败
	{
		CleanUp();
		m_iLastErrorNumber	= ERR_AVI_FILE_ERROR;
		m_sLastErrorDescribe.Format("AVIFileCreateStream 函数出错:%ld",hr);
		return ERR_AVI_FILE_ERROR;
	}

	//	创建压缩信息
	LPAVICOMPRESSOPTIONS FAR	m_pFar[1];
	m_pFar[0]	= &m_AviCompressOptions;

	BOOL	bResult;

//	bResult	= ::AVISaveOptions(NULL, ICMF_CHOOSE_KEYFRAME|ICMF_CHOOSE_DATARATE|ICMF_CHOOSE_PREVIEW, 1, &m_pAviStream, m_pFar);
	bResult	= TRUE;

	m_AviCompressOptions.fccType			= 0;
	m_AviCompressOptions.fccHandler			= 1684633187; // 1668707181;
	m_AviCompressOptions.dwKeyFrameEvery	= 0;
	m_AviCompressOptions.dwQuality			= 10000; // 8500;
	m_AviCompressOptions.dwBytesPerSecond	= 0;
	m_AviCompressOptions.dwFlags			= 8;
	m_AviCompressOptions.lpFormat			= NULL; // 0x0;
	m_AviCompressOptions.cbFormat			= 0;
	m_AviCompressOptions.lpParms			= (VOID *)(4806108); // (VOID *)(0x00509e60);
	m_AviCompressOptions.cbParms			= 0;//4
	m_AviCompressOptions.dwInterleaveEvery	= 0;

/*
CString		sInfo;
CHAR		sBuf[100];

sprintf(sBuf, "fccType			= %ld\r\n", m_AviCompressOptions.fccType);
sInfo		+= sBuf;
sprintf(sBuf, "fccHandler		= %ld\r\n", m_AviCompressOptions.fccHandler);
sInfo		+= sBuf;
sprintf(sBuf, "dwKeyFrameEvery		= %ld\r\n", m_AviCompressOptions.dwKeyFrameEvery);
sInfo		+= sBuf;
sprintf(sBuf, "dwQuality		= %ld\r\n", m_AviCompressOptions.dwQuality);
sInfo		+= sBuf;
sprintf(sBuf, "dwBytesPerSecond	= %ld\r\n", m_AviCompressOptions.dwBytesPerSecond);
sInfo		+= sBuf;
sprintf(sBuf, "dwFlags			= %ld\r\n", m_AviCompressOptions.dwFlags);
sInfo		+= sBuf;
sprintf(sBuf, "lpFormat		= %ld\r\n", (DWORD)(m_AviCompressOptions.lpFormat));
sInfo		+= sBuf;
sprintf(sBuf, "cbFormat		= %ld\r\n", m_AviCompressOptions.cbFormat);
sInfo		+= sBuf;
sprintf(sBuf, "lpParms			= %ld\r\n", (DWORD)(m_AviCompressOptions.lpParms));
sInfo		+= sBuf;
sprintf(sBuf, "cbParms			= %ld\r\n", (DWORD)(m_AviCompressOptions.cbParms));
sInfo		+= sBuf;
sprintf(sBuf, "dwInterleaveEvery	= %ld\r\n", (DWORD)(m_AviCompressOptions.dwInterleaveEvery));
sInfo		+= sBuf;
FILE	*fp	= fopen("c:\\bxx\\temp.txt", "w");
if	(NULL != fp)
{
	fprintf(fp, sInfo.GetBuffer(sInfo.GetLength()));
	fclose(fp);
}
*/
//AfxMessageBox(sInfo);

//    DWORD       fccType;				      /* stream type, for consistency */
//    DWORD       fccHandler;                 /* compressor */
//    DWORD       dwKeyFrameEvery;            /* keyframe rate */
//    DWORD       dwQuality;                  /* compress quality 0-10,000 */
//    DWORD       dwBytesPerSecond;           /* bytes per second */
//    DWORD       dwFlags;                    /* flags... see below */
//    LPVOID      lpFormat;                   /* save format */
//    DWORD       cbFormat;
//    LPVOID      lpParms;                    /* compressor options */
//    DWORD       cbParms;
//    DWORD       dwInterleaveEvery;          /* for non-video streams only */

	if	(FALSE	== bResult)
	//	创建压缩信息失败
	{
		CleanUp();
		m_iLastErrorNumber	= ERR_AVI_FILE_ERROR;
		m_sLastErrorDescribe.Format("AVISaveOptions 函数出错");
		return ERR_AVI_FILE_ERROR;
	}


	//	创建压缩的视频流
	hr	= ::AVIMakeCompressedStream(&m_pCompressedAviStream, m_pAviStream, &m_AviCompressOptions, NULL);

	if	(AVIERR_OK	!= hr)
	//	创建压缩视频流失败
	{
		CleanUp();
		m_iLastErrorNumber	= ERR_AVI_FILE_ERROR;
		m_sLastErrorDescribe.Format("AVIMakeCompressedStream 函数出错:%ld", hr);
		return ERR_AVI_FILE_ERROR;
	}

	//	设置视频流格式
	hr	= ::AVIStreamSetFormat(m_pCompressedAviStream, 0, m_pFormat, m_iFormatLength);
	if	(AVIERR_OK	!= hr)
	//	设置视频流格式错误
	{
		CleanUp();
		m_iLastErrorNumber	= ERR_AVI_FILE_ERROR;
		m_sLastErrorDescribe.Format("AVIStreamSetFormat 函数出错:%ld", hr);
		return ERR_AVI_FILE_ERROR;
	}

	//	创建 AVI 文件正确
	return ERR_OK;
}

/*
	APPEND A SAMPLE AT THE END OF THE CREATED AVI STREAM FROM A BITMAP FILE
	ARGUMENTS:
		sBitmapFilePathName		-	THE PATHNAME OF A BITMAP FILE THAT YOU WANT TO APPEND TO THE STREAM
	RETURN VALUE:
		ERR_OK					-	SUCCESS
		ERR_CANNOT_OPEN_FILE	-	CANNOT OPEN THE SPECIFIED FILE
		ERR_READ_FILE_ERROR		-	READ FILE ERROR
		ERR_BAD_FORMAT			-	FILE FORMAT ERROR, SUCH AS NO BITMAP IDENTITY 'BM'
		ERR_OUT_OF_MEMORY		-	OUT OF MEMORY
		ERR_IMAGE_SIZE_ERROR	-	IMAGE SIZE CONFLICT WITH THE PREDEFINE SIZE IN STREAM FORMAT
		ERR_AVI_FILE_ERROR		-	ERROR OCCUR WHEN WRITE DATA TO STREAM
*/
HRESULT
CAVITools::AddFileFrame(CHAR *sBitmapFilePathName)
{
	BITMAPFILEHEADER	bfh;
	long				datasize;
	HRESULT				hr;
	CHAR				*pBuffer;

	//	没有创建的成功压缩流
	if (NULL == m_pCompressedAviStream)
	{
		m_iLastErrorNumber	= ERR_AVI_FILE_NOT_CREATE;
		m_sLastErrorDescribe.Format("AVI 文件没有创建");
		return	ERR_AVI_FILE_NOT_CREATE;
	}

	//	没有指定正确的位图文件名
	if (NULL == sBitmapFilePathName)
	{
		m_iLastErrorNumber	= ERR_ARGUMENTS_ERROR;
		m_sLastErrorDescribe.Format("参数错误:文件名指针为空");
		return	ERR_ARGUMENTS_ERROR;
	}
	
	//	打开指定的位图文件
	FILE	*fp	= fopen(sBitmapFilePathName, "rb");
	if (NULL == fp)
	//	无法正确打开文件
	{
		m_iLastErrorNumber	= ERR_CANNOT_OPEN_FILE;
		m_sLastErrorDescribe.Format("无法打开文件 %s",sBitmapFilePathName);
		return ERR_CANNOT_OPEN_FILE;
	}

	//	读取文件头
	if	(1 != fread(&bfh,sizeof(BITMAPFILEHEADER),1,fp))
	{
		fclose(fp);
		m_iLastErrorNumber	= ERR_READ_FILE_ERROR;
		m_sLastErrorDescribe.Format("读取文件头出错:%s",sBitmapFilePathName);
		return ERR_READ_FILE_ERROR;
	}

	//	Validate File Type
	if (0x4d42 != bfh.bfType)
	{
		fclose(fp);
		m_iLastErrorNumber	= ERR_BAD_FORMAT;
		m_sLastErrorDescribe.Format("文件格式错误:文件 %s 的前两个字节不是 'BM'",sBitmapFilePathName);
		return ERR_BAD_FORMAT;
	}

	//	Alloc Memory
	datasize	= bfh.bfSize - sizeof(BITMAPFILEHEADER);
	pBuffer		= new CHAR[datasize];
	if (NULL == pBuffer)
	{
		fclose(fp);
		m_iLastErrorNumber	= ERR_OUT_OF_MEMORY;
		m_sLastErrorDescribe.Format("内存溢出");
		return ERR_OUT_OF_MEMORY;
	}

	//	Read Entire File
	if (1 != fread(m_pBuffer,datasize,1,fp))
	{
		fclose(fp);
		delete pBuffer;
		m_iLastErrorNumber	= ERR_READ_FILE_ERROR;
		m_sLastErrorDescribe.Format("读取文件内容出错:%s",sBitmapFilePathName);
		return ERR_READ_FILE_ERROR;
	}

	//	Close File
	fclose(fp);

	BITMAPINFOHEADER	*pbih		= NULL;
	RGBQUAD				*pPattle	= NULL;
	CHAR				*pBits		= NULL;

	//	Init Pointer
	pbih	= (BITMAPINFOHEADER *)pBuffer;
	pBits	= pBuffer + bfh.bfOffBits - sizeof(BITMAPFILEHEADER);
	if (8 == pbih->biBitCount)
	{
		pPattle	= (RGBQUAD *)(m_pBuffer + pbih->biClrUsed * sizeof(RGBQUAD));
	}
	else if (16 == pbih->biBitCount || 24 == pbih->biBitCount)
	{
		pPattle		= NULL;
	}
	else
	{
		delete pBuffer;
		m_iLastErrorNumber	= ERR_BAD_FORMAT;
		m_sLastErrorDescribe.Format("文件格式错误:不支持 %d 位颜色的图象",(INT)pbih->biBitCount);
		return ERR_BAD_FORMAT;
	}

	//	Validate Image Size
	if (pbih->biWidth != m_iWidth || pbih->biHeight != m_iHeight)
	{
		delete pBuffer;
		m_iLastErrorNumber	= ERR_IMAGE_SIZE_ERROR;
		m_sLastErrorDescribe.Format("该图象的大小与预定义的大小不匹配");
		return ERR_IMAGE_SIZE_ERROR;
	}

	//	Write Compressed Avi Stream
	hr	= ::AVIStreamWrite(m_pCompressedAviStream,
		m_iCurrentFrameCount,
		1,
		(LPBYTE)pBits,
		pbih->biSizeImage,
		AVIIF_KEYFRAME,
		NULL,
		NULL);

	if (AVIERR_OK != hr)
	{
		delete pBuffer;
		m_iLastErrorNumber	= ERR_IMAGE_SIZE_ERROR;
		m_sLastErrorDescribe.Format("AVIStreamWrite 函数出错:%ld",hr);
		return ERR_AVI_FILE_ERROR;
	}

	delete pBuffer;
	m_iCurrentFrameCount++;

	m_iLastErrorNumber	= ERR_OK;
	m_sLastErrorDescribe.Empty();
	return ERR_OK;
}

/*
	从内存中向 AVI 流中增加一侦
	输入参数:
		pBits					-	位图数据内存地址
	返回值:
		ERR_OK					-	执行成功
		ERR_AVI_FILE_NOT_CREATE	-	文件没有创建
		ERR_ARGUMENTS_ERROR		-	参数错误
		ERR_AVI_FILE_ERROR		-	添加时出现错误

*/
HRESULT
CAVITools::AddMemFrame(CHAR *pBits)
{
	HRESULT		hr;

	//	验证压缩流是否可用
	if (NULL == m_pCompressedAviStream)
	{
		m_iLastErrorNumber	= ERR_AVI_FILE_NOT_CREATE;
		m_sLastErrorDescribe.Format("AVI 文件没有创建");
		return	ERR_AVI_FILE_NOT_CREATE;
	}

	//	验证位图数据是否可能可用
	if (NULL == pBits)
	{
		m_iLastErrorNumber	= ERR_ARGUMENTS_ERROR;
		m_sLastErrorDescribe.Format("参数错误:指针为空");
		return	ERR_ARGUMENTS_ERROR;
	}

	//	增加侦
	hr	= ::AVIStreamWrite(m_pCompressedAviStream,
		m_iCurrentFrameCount,
		1,
		(LPBYTE)pBits,
		m_iFrameSize,
		AVIIF_KEYFRAME,
		NULL,
		NULL);
	
	if (AVIERR_OK != hr)
	{
		m_iLastErrorNumber	= ERR_AVI_FILE_ERROR;
		m_sLastErrorDescribe.Format("AVIStreamWrite 函数执行失败:%ld",hr);
		return	ERR_AVI_FILE_ERROR;
	}

	//	增加侦数量
	m_iCurrentFrameCount++;

	//	返回成功标志
	m_iLastErrorNumber	= ERR_OK;
	m_sLastErrorDescribe.Empty();
	return ERR_OK;
}

/*
	释放资源
*/
BOOL
CAVITools::CleanUp()
{
	//	释放压缩流
	if (NULL != m_pCompressedAviStream)
	{
		::AVIStreamRelease(m_pCompressedAviStream);
		m_pCompressedAviStream	= NULL;
	}

	//	释放 AVI 流
	if (NULL != m_pAviStream)
	{
		::AVIStreamRelease(m_pAviStream);
		m_pAviStream	= NULL;
	}

	//	释放文件
	if (NULL != m_pAviFile)
	{
		::AVIFileRelease(m_pAviFile);
		m_pAviFile		= NULL;
	}

	//	释放分配的内存
	if (NULL != m_pBuffer)
	{
		delete m_pBuffer;
		m_pBuffer		= NULL;
	}

	//	成员数据初始化
	m_strAviFileName		= _T("");
	m_iCurrentFrameCount	= 0;
	memset(&m_AviStreamInfo, 0, sizeof(AVISTREAMINFO));
	memset(&m_AviCompressOptions, 0, sizeof(AVICOMPRESSOPTIONS));

	return	(TRUE);
}

/*
	从位图文件中读取格式,设置流格式
	输入参数:
		sBmpFile		-	用于设置格式的位图文件磁盘位置
	返回值:
*/
HRESULT
CAVITools::SetStreamFormatFromFile(CHAR *sBmpFile)
{
	INT					needlength;
	INT					pattlelength;
	BITMAPFILEHEADER	bfh;
	BITMAPINFOHEADER	bih;
	CHAR				*pattlebuf	= NULL;
	FILE				*fp	= NULL;

	//	如果曾经设置过格式,将其删除
	if (NULL != m_pFormat)
	{
		delete m_pFormat;
		m_pFormat	= NULL;
	}

	//	打开文件
	if (NULL == (fp	= fopen(sBmpFile,"rb")))
	{
		m_iLastErrorNumber	= ERR_CANNOT_OPEN_FILE;
		m_sLastErrorDescribe.Format("无法打开文件:%s",sBmpFile);
		return ERR_CANNOT_OPEN_FILE;
	}

	//	读取文件头数据

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -