📄 avitools.cpp
字号:
if (1 != fread(&bfh,sizeof(BITMAPFILEHEADER),1,fp))
{
fclose(fp);
m_iLastErrorNumber = ERR_READ_FILE_ERROR;
m_sLastErrorDescribe.Format("读取文件头出错:%s",sBmpFile);
return ERR_READ_FILE_ERROR;
}
// 验证文件格式 'BM'
if (0x4d42 != bfh.bfType)
{
fclose(fp);
m_iLastErrorNumber = ERR_BAD_FORMAT;
m_sLastErrorDescribe.Format("文件格式错误:没有 'BM' 标志:%s",sBmpFile);
return ERR_BAD_FORMAT;
}
// 读取信息头数据
if (1 != fread(&bih,sizeof(BITMAPINFOHEADER),1,fp))
{
fclose(fp);
m_iLastErrorNumber = ERR_READ_FILE_ERROR;
m_sLastErrorDescribe.Format("读取信息头数据:%s",sBmpFile);
return ERR_READ_FILE_ERROR;
}
// 8 bits bitmap
if (8 == bih.biBitCount)
{
pattlelength = bih.biClrUsed * sizeof(RGBQUAD);
}
// 16 or 24 bits bitmap
else if (16 == bih.biBitCount || 24 == bih.biBitCount)
{
pattlelength = 0;
}
// other
else
{
fclose(fp);
m_iLastErrorNumber = ERR_BAD_FORMAT;
m_sLastErrorDescribe.Format("不能处理该图象,颜色错误:%s",sBmpFile);
return ERR_BAD_FORMAT;
}
needlength = sizeof(BITMAPINFOHEADER) + pattlelength;
if (0 < pattlelength)
{
pattlebuf = new CHAR[pattlelength];
if (NULL == pattlebuf)
{
fclose(fp);
m_iLastErrorNumber = ERR_OUT_OF_MEMORY;
m_sLastErrorDescribe.Format("内存溢出");
return ERR_OUT_OF_MEMORY;
}
if (1 != fread(pattlebuf,pattlelength,1,fp))
{
delete pattlebuf;
fclose(fp);
m_iLastErrorNumber = ERR_READ_FILE_ERROR;
m_sLastErrorDescribe.Format("读取调色板出错:%s",sBmpFile);
return ERR_READ_FILE_ERROR;
}
}
fclose(fp);
// 为流格式分配空间,包括信息头和可选调色板
m_pFormat = (BITMAPINFOHEADER *)(new CHAR[needlength]);
if (NULL == m_pFormat)
{
delete pattlebuf;
m_iLastErrorNumber = ERR_OUT_OF_MEMORY;
m_sLastErrorDescribe.Format("内存溢出");
return ERR_OUT_OF_MEMORY;
}
// 复制格式内容
memcpy(m_pFormat,&bih,sizeof(BITMAPINFOHEADER));
if (0 < pattlelength)
{
memcpy((CHAR *)m_pFormat + sizeof(BITMAPINFOHEADER),pattlebuf,pattlelength);
delete pattlebuf;
}
m_iFormatLength = needlength;
m_iFrameSize = bih.biSizeImage;
m_iLastErrorNumber = ERR_OK;
m_sLastErrorDescribe.Empty();
return ERR_OK;
}
// Unfinished
HRESULT
CAVITools::SetStreamFormatFromMemory(BITMAPINFOHEADER *pData,BOOL bHasPattle)
{
INT needlength;
if (NULL != m_pFormat)
{
delete m_pFormat;
m_pFormat = NULL;
}
if (8 == pData->biBitCount)
{
needlength = sizeof(BITMAPINFOHEADER) + pData->biClrUsed * sizeof(RGBQUAD);
}
else if (16 == pData->biBitCount || 24 == pData->biBitCount)
{
if (FALSE != bHasPattle)
return FALSE;
needlength = sizeof(BITMAPINFOHEADER);
}
else
{
return FALSE;
}
m_pFormat = (BITMAPINFOHEADER *)(new CHAR[needlength]);
if (NULL == m_pFormat)
{
return FALSE;
}
memcpy(m_pFormat,pData,needlength);
m_iFormatLength = needlength;
m_iFrameSize = pData->biSizeImage;
return TRUE;
}
/*
分解 AVI 文件为位图文件
输入参数:
sAviFileName - 需要分解的 AVI 文件位置
sTargetPath - 目标路径
iCount - 分解的位图文件数目
返回值:
ERR_OK - 分解成功
*/
HRESULT
CAVITools::SplitAvi(CHAR *sAviFileName, CHAR *sTargetPath, INT *iCount)
{
// long lBytes,lSamples; // Samples And Bytes That Read From Stream
AVIFILEINFO AviFileInfo; // Avi File Info
AVISTREAMINFO AviStreamInfo; // Avi Stream Info
PAVIFILE pAviFile = NULL;
PAVISTREAM pAviStream = NULL;
PGETFRAME pGetFrame = NULL;
HDRAWDIB hDrawDib = NULL;
FILE *fp = NULL;
CHAR *sBmpFileName = NULL;
HRESULT hr = NULL; // Common Var, The Function's Result Handle
HRESULT hReturnValue = ERR_OK;
LPVOID lpFrameBuffer = NULL;
// Open An Avi File, Get It's Handle Pointer
hr = ::AVIFileOpen(&pAviFile,sAviFileName,OF_READ,NULL);
if (hr)
{
hReturnValue = ERR_AVI_OPEN_ERROR;
goto _ReleaseMemory;
}
// Get Avi File Info
hr = ::AVIFileInfo(pAviFile,&AviFileInfo,sizeof(AVIFILEINFO));
if (hr)
{
hReturnValue = ERR_AVI_INFO_ERROR;
goto _ReleaseMemory;
}
// Open A Stream From An Opened File, Get It's Handle Pointer
hr = ::AVIFileGetStream(pAviFile,&pAviStream,streamtypeVIDEO,0);
if (hr)
{
if (AVIERR_NODATA == hr)
{
}
else if (AVIERR_MEMORY == hr)
{
}
hReturnValue = ERR_AVI_GETSTREAM_ERROR;
goto _ReleaseMemory;
}
// Get Stream Information
hr = ::AVIStreamInfo(pAviStream,&AviStreamInfo,sizeof(AVISTREAMINFO));
if (hr)
{
hReturnValue = ERR_AVI_STREAMINFO_ERROR;
goto _ReleaseMemory;
}
// Get Frame Open
pGetFrame = ::AVIStreamGetFrameOpen(pAviStream,(LPBITMAPINFOHEADER)AVIGETFRAMEF_BESTDISPLAYFMT);
if (!pGetFrame)
{
hReturnValue = ERR_AVI_GETFRAME_ERROR;
goto _ReleaseMemory;
}
sBmpFileName = new CHAR[strlen(sTargetPath) + 12];
if (NULL == sBmpFileName)
{
hReturnValue = ERR_OUT_OF_MEMORY;
goto _ReleaseMemory;
}
strcpy(sBmpFileName,sTargetPath);
if ('\\' != sBmpFileName[strlen(sBmpFileName) - 1])
{
strcat(sBmpFileName,"\\");
}
strcat(sBmpFileName,"00000.bmp");
//////////////////////////////
INT n,i;
n = strlen(sBmpFileName) - 5;
for (i = 0;; i++)
{
if ((INT)AviStreamInfo.dwLength <= i)
{
*iCount = i;
hReturnValue = ERR_OK;
goto _ReleaseMemory;
}
sBmpFileName[n - 4] = '0' + i % 100000 / 10000;
sBmpFileName[n - 3] = '0' + i % 10000 / 1000;
sBmpFileName[n - 2] = '0' + i % 1000 / 100;
sBmpFileName[n - 1] = '0' + i % 100 / 10;
sBmpFileName[n - 0] = '0' + i % 10 / 1;
lpFrameBuffer = ::AVIStreamGetFrame(pGetFrame,i);
if (NULL == lpFrameBuffer)
{
hReturnValue = ERR_AVI_GETFRAME_ERROR;
goto _ReleaseMemory;
}
// Save The Memory Frame To A Specified File
// SaveDib(fn,framebuffer,width,height,colorbits);
}
hReturnValue = ERR_OK;
_ReleaseMemory:
if (NULL != sBmpFileName) delete sBmpFileName;
if (NULL != pGetFrame) ::AVIStreamGetFrameClose(pGetFrame);
if (NULL != pAviStream) ::AVIStreamRelease(pAviStream);
if (NULL != pAviFile) ::AVIFileRelease(pAviFile);
return hReturnValue;
}
/*
SAVE BITMAP FILE TO DISK
ARGUMENTS:
sFileName - THE PATHNAME OF BITMAP THAT YOU WANT TO SAVE
pData - ADDRESS OF BITMAP BUFFER, INCLUDE INFOHEADER,
OPTIONAL PATTLE AND BITSDATA
RETURN VALUE:
ERR_OK - SUCCESS
ERR_BAD_FORMAT - BUFFER HAS BAD OR UNKNOWN FORMAT
ERR_CANNOT_OPEN_FILE - CANNOT OPEN FILE TO WRITE
ERR_WRITE_FILE_ERROR - AN ERROR OCCUR WHILE WRITING FILE
*/
HRESULT
CAVITools::SaveBMP(CHAR *sFileName, BITMAPINFOHEADER *pData)
{
BITMAPFILEHEADER bfh;
FILE *fp = NULL;
// SUPPORT ONLY 8 bits, 16 bits AND 24 bits FORMAT
if (8 != pData->biBitCount && 16 != pData->biBitCount && 24 != pData->biBitCount)
{
m_iLastErrorNumber = ERR_BAD_FORMAT;
m_sLastErrorDescribe = "不支持该图象的颜色数目";
return ERR_BAD_FORMAT;
}
bfh.bfType = 0x4d42; // "BM";
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
// CALCULATE FILE SIZE AND BITSDATA OFFSET ADDRESS
bfh.bfSize = sizeof(bfh);
bfh.bfSize += pData->biSize;
if (8 == pData->biBitCount)
bfh.bfSize += pData->biClrUsed * sizeof(RGBQUAD);
bfh.bfOffBits = bfh.bfSize;
bfh.bfSize += pData->biSizeImage;
// OPEN FILE FOR BINARY WRITE
if (NULL == (fp = fopen(sFileName,"wb")))
{
m_iLastErrorNumber = ERR_CANNOT_OPEN_FILE;
m_sLastErrorDescribe.Format("无法打开文件 %s",sFileName);
return ERR_CANNOT_OPEN_FILE;
}
// WRITE DATA
if (1 != fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fp) ||
1 != fwrite((CHAR *)pData,bfh.bfSize - sizeof(BITMAPFILEHEADER),1,fp))
{
fclose(fp);
m_iLastErrorNumber = ERR_WRITE_FILE_ERROR;
m_sLastErrorDescribe.Format("无法写入文件 %s",sFileName);
return ERR_WRITE_FILE_ERROR;
}
fclose(fp);
// SUCCESS, RETURN OK
m_iLastErrorNumber = ERR_OK;
m_sLastErrorDescribe.Empty();
return ERR_OK;
}
/*
RETURN THE ERROR NUMBER AND DESCRIBE OF THE LAST ERROR
ARGUMENTS:
sDescribe - REFERS TO A CSTRING VARIABLE TO RETURN ERROR DESCRIBE
iErrorNumber - REFERS TO A INTEGER VARIABLE TO RETURN ERROR NUMBER
RETURN VALUE:
TRUE - HAS ERROR
FALSE - THERE ISN'T ANY ERROR
*/
BOOL
CAVITools::GetLastError(CString &sDescribe, INT &iErrorNumber)
{
sDescribe = m_sLastErrorDescribe;
iErrorNumber = m_iLastErrorNumber;
return (ERR_OK == m_iLastErrorNumber) ? (FALSE) : (TRUE);
}
BOOL
CAVITools::GetLastError(CString &sDescribe)
{
sDescribe = m_sLastErrorDescribe;
return (ERR_OK == m_iLastErrorNumber) ? (FALSE) : (TRUE);
}
/*
在指定的设备上显示 AVI 图象
参数:
sFileName - AVI 文件名
hWnd - 指定的设备
*/
BOOL
CAVITools::ShowAvi(CHAR *sFileName, HWND hWnd,
INT iVideoID, INT iDelay,
INT iBeginFrame, INT iEndFrame,
int xDst, int yDst, int dxDst, int dyDst,
int xSrc, int ySrc, int dxSrc, int dySrc)
{
memset(&m_ShowAviArg, 0, sizeof(SHOW_AVI_ARG));
strcpy(m_ShowAviArg.sFileName, sFileName);
SHOW_AVI_ARG *p = &m_ShowAviArg;
p->xDst = xDst;
p->yDst = yDst;
p->dxDst = dxDst;
p->dyDst = dyDst;
p->xSrc = xSrc;
p->ySrc = ySrc;
p->dxSrc = dxSrc;
p->dySrc = dySrc;
p->hWnd = hWnd;
p->iDelay = iDelay;
p->bLoop = TRUE;
p->iVideoID = iVideoID;
p->iBeginFrame = iBeginFrame;
p->iEndFrame = iEndFrame;
p->iControl = CONTROL_PLAY;
::AfxBeginThread(ShowAviThread, (LPVOID)p);
return TRUE;
}
UINT
ShowAviThread(LPVOID lParam)
{
SHOW_AVI_ARG* pArg = (SHOW_AVI_ARG *)lParam;
HDRAWDIB hDrawDib = NULL;
HDC hDC = NULL;
PAVIFILE pAviFile = NULL;
PAVISTREAM pAviStream = NULL;
PGETFRAME pGetFrame = NULL;
LPVOID lpFrameBuf = NULL;
HRESULT hr = NULL;
BOOL bReturnValue = FALSE;
INT iCurrentFrame = -1;
AVISTREAMINFO AviStreamInfo;
hr = ::AVIFileOpen(&pAviFile, pArg->sFileName, OF_READ, NULL);
if (AVIERR_OK != hr) goto _ReleaseMemory;
hr = ::AVIFileGetStream(pAviFile, &pAviStream, streamtypeVIDEO, pArg->iVideoID);
if (AVIERR_OK != hr) goto _ReleaseMemory;
hr = ::AVIStreamInfo(pAviStream, &AviStreamInfo, sizeof(AVISTREAMINFO));
if (AVIERR_OK != hr) goto _ReleaseMemory;
pGetFrame = ::AVIStreamGetFrameOpen(pAviStream, NULL);
if (NULL == pGetFrame) goto _ReleaseMemory;
hDrawDib = ::DrawDibOpen();
if (NULL == hDrawDib) goto _ReleaseMemory;
hDC = ::GetDC(pArg->hWnd);
if (NULL == hDC) goto _ReleaseMemory;
if ((INT)AviStreamInfo.dwLength <= 0) goto _ReleaseMemory;
if (pArg->iBeginFrame < 0)
pArg->iBeginFrame = 0;
else if (pArg->iBeginFrame >= (INT)AviStreamInfo.dwLength)
pArg->iBeginFrame = (INT)AviStreamInfo.dwLength - 1;
if (pArg->iEndFrame < 0)
pArg->iEndFrame = (INT)AviStreamInfo.dwLength - 1;
else if (pArg->iEndFrame >= (INT)AviStreamInfo.dwLength)
pArg->iEndFrame = (INT)AviStreamInfo.dwLength - 1;
if (pArg->iEndFrame < pArg->iBeginFrame)
goto _ReleaseMemory;
iCurrentFrame = pArg->iBeginFrame;
for (;;)
{
if (CONTROL_PLAY != pArg->iControl)
{
if (CONTROL_PAUSE == pArg->iControl)
{
while (CONTROL_PAUSE == pArg->iControl) ::Sleep(100);
if (CONTROL_STOP == pArg->iControl) goto _ReleaseMemory;
}
else if (CONTROL_STOP == pArg->iControl)
{
goto _ReleaseMemory;
}
}
if (iCurrentFrame >= (INT)AviStreamInfo.dwLength)
{
if (FALSE == pArg->bLoop) break;
else iCurrentFrame = pArg->iBeginFrame;
}
lpFrameBuf = ::AVIStreamGetFrame(pGetFrame, iCurrentFrame);
if (NULL == lpFrameBuf) goto _ReleaseMemory;
::DrawDibDraw(hDrawDib, hDC,
pArg->xDst, pArg->yDst, pArg->dxDst, pArg->dyDst,
(BITMAPINFOHEADER *)lpFrameBuf, NULL,
pArg->xSrc, pArg->ySrc, pArg->dxSrc, pArg->dySrc,
0);
::Sleep(pArg->iDelay);
iCurrentFrame++;
}
bReturnValue = TRUE;
_ReleaseMemory:
if (NULL != hDC) ::ReleaseDC(pArg->hWnd, hDC);
if (NULL != hDrawDib) ::DrawDibClose(hDrawDib);
if (NULL != pGetFrame) ::AVIStreamGetFrameClose(pGetFrame);
if (NULL != pAviStream) ::AVIStreamRelease(pAviStream);
if (NULL != pAviFile) ::AVIFileRelease(pAviFile);
return UINT(bReturnValue);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -