Files
envi-code/SourceCode/Code2026/tg_shs/shs_kerncmd/WRITEAVI.CPP
T
2026-09-28 15:28:50 +08:00

438 lines
10 KiB
C++

/****************************************************************************
*
* WRITEAVI.C Modified 2003
*
* Creates the file OUTPUT.AVI, an AVI file consisting of a rotating clock
* face. This program demonstrates using the functions in AVIFILE.DLL
* to make writing AVI files simple.
*
* This is a stripped-down example; a real application would have a user
* interface and check for errors.
*
***************************************************************************/
#include "stdafx.h"
#include <windowsx.h>
#include <memory.h>
#include <mmsystem.h>
#include <vfw.h>
#include "writeavi.h"
CAVIFile::CAVIFile()
: m_bHasSaveOptionsDialog(TRUE),
m_nColorNum(8)//256色
{
m_pfile = NULL;
m_ps = NULL;
m_psCompressed = NULL;
m_psText = NULL;
m_pOpts[0] = &m_opts;
WORD wVer = HIWORD(VideoForWindowsVersion());
if (wVer < 0x010A)
{
// oops, we are too old, blow out of here
m_bOK = FALSE;
}
else
{
AVIFileInit();
}
m_hSaveOptionsParentWnd = NULL;
}
CAVIFile::CAVIFile(LPCTSTR lpszFileName, int xdim, int ydim, int rate)
: m_sFileName(lpszFileName),
m_nXDim(xdim), m_nYDim(ydim),
m_bOK(TRUE), m_nFrame(0), m_nRate(rate),
m_bHasSaveOptionsDialog(TRUE),
m_nColorNum(8)//256色
{
m_pfile = NULL;
m_ps = NULL;
m_psCompressed = NULL;
m_psText = NULL;
m_pOpts[0] = &m_opts;
WORD wVer = HIWORD(VideoForWindowsVersion());
if (wVer < 0x010A)
{
// oops, we are too old, blow out of here
m_bOK = FALSE;
}
else
{
AVIFileInit();
}
}
CAVIFile::~CAVIFile()
{
if (m_ps)
AVIStreamClose(m_ps);
if (m_psCompressed)
AVIStreamClose(m_psCompressed);
if (m_psText)
AVIStreamClose(m_psText);
if (m_pfile)
AVIFileClose(m_pfile);
WORD wVer = HIWORD(VideoForWindowsVersion());
if (wVer >= 0x010A)
{
AVIFileExit();
}
}
void CAVIFile::Init(LPCTSTR lpszFileName, int xdim, int ydim, int rate)
{
m_sFileName = lpszFileName;
m_nXDim = xdim;
m_nYDim = ydim;
m_bOK = TRUE;
m_nFrame = 0;
m_nRate = rate;
}
BOOL CAVIFile::Compress()
{
HRESULT hr;
hr = AVIMakeCompressedStream(&m_psCompressed, m_ps, &m_opts, NULL);
if (hr != AVIERR_OK)
return FALSE;
AVIFileRelease(m_pfile);
return TRUE;
}
HANDLE CAVIFile::MakeDib( HBITMAP hbitmap, UINT bits )
{
HANDLE hdib ;
HDC hdc ;
BITMAP bitmap ;
UINT wLineLen ;
DWORD dwSize ;
DWORD wColSize ;
LPBITMAPINFOHEADER lpbi ;
LPBYTE lpBits ;
GetObject(hbitmap,sizeof(BITMAP),&bitmap) ;
//
// DWORD align the width of the DIB
// Figure out the size of the colour table
// Calculate the size of the DIB
//
wLineLen = (bitmap.bmWidth*bits+31)/32 * 4;
wColSize = sizeof(RGBQUAD)*((bits <= 8) ? 1<<bits : 0);
dwSize = sizeof(BITMAPINFOHEADER) + wColSize +
(DWORD)(UINT)wLineLen*(DWORD)(UINT)bitmap.bmHeight;
//
// Allocate room for a DIB and set the LPBI fields
//
hdib = GlobalAlloc(GHND,dwSize);
if (!hdib)
return hdib ;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib) ;
lpbi->biSize = sizeof(BITMAPINFOHEADER) ;
lpbi->biWidth = bitmap.bmWidth ;
lpbi->biHeight = bitmap.bmHeight ;
lpbi->biPlanes = 1 ;
lpbi->biBitCount = (WORD) bits ;
lpbi->biCompression = BI_RGB ;
lpbi->biSizeImage = dwSize - sizeof(BITMAPINFOHEADER) - wColSize ;
lpbi->biXPelsPerMeter = 0 ;
lpbi->biYPelsPerMeter = 0 ;
lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
lpbi->biClrImportant = 0 ;
//
// Get the bits from the bitmap and stuff them after the LPBI
//
lpBits = (LPBYTE)(lpbi+1)+wColSize ;
hdc = CreateCompatibleDC(NULL) ;
GetDIBits(hdc,hbitmap,0,bitmap.bmHeight,lpBits,(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
// Fix this if GetDIBits messed it up....
lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
DeleteDC(hdc) ;
GlobalUnlock(hdib);
return hdib ;
}
BOOL CAVIFile::AddFrame(CBitmap& bmp)
{
HRESULT hr;
if (!m_bOK)
return FALSE;
LPBITMAPINFOHEADER alpbi =(LPBITMAPINFOHEADER)GlobalLock(MakeDib(bmp, m_nColorNum)); //24为24位真彩
if (alpbi == NULL)
return FALSE;
//宽和高是否一致
int nXDim = alpbi->biWidth;
int nYDim = alpbi->biHeight;
if (m_nXDim>=0 && m_nXDim != nXDim) {
GlobalFreePtr(alpbi);
return FALSE;
}
if (m_nYDim>=0 && m_nYDim != nYDim) {
GlobalFreePtr(alpbi);
return FALSE;
}
m_nXDim = nXDim;
m_nYDim = nYDim;
if (m_nFrame == 0)
{
hr = AVIFileOpen(&m_pfile, // returned file pointer
m_sFileName, // file name
OF_WRITE | OF_CREATE, // mode to open file with
NULL); // use handler determined
// from file extension....
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
m_bOK = FALSE;
return FALSE;
}
_fmemset(&m_strhdr, 0, sizeof(m_strhdr));
m_strhdr.fccType = streamtypeVIDEO; // stream type
m_strhdr.fccHandler = 0;
m_strhdr.dwScale = 1;
m_strhdr.dwRate = m_nRate; // 80 fps avi rate
m_strhdr.dwSuggestedBufferSize = alpbi->biSizeImage;
SetRect(&m_strhdr.rcFrame, 0, 0, // rectangle for stream
m_nXDim,m_nYDim);
// And create the stream;
hr = AVIFileCreateStream(m_pfile, // file pointer
&m_ps, // returned stream pointer
&m_strhdr); // stream header
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
m_bOK = FALSE;
return FALSE;
}
_fmemset(&m_opts, 0, sizeof(m_opts));
//是否屏蔽掉属性对话框
if (m_bHasSaveOptionsDialog) {
if (!AVISaveOptions(m_hSaveOptionsParentWnd,0,1,
&m_ps,(LPAVICOMPRESSOPTIONS FAR *)&m_pOpts)) {
GlobalFreePtr(alpbi);
m_bOK = FALSE;
return FALSE;
}
}
hr = AVIMakeCompressedStream(&m_psCompressed, m_ps, &m_opts, NULL);
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
m_bOK = FALSE;
return FALSE;
}
hr = AVIStreamSetFormat(m_psCompressed, 0,
alpbi, // stream format
alpbi->biSize + // format size
alpbi->biClrUsed * sizeof(RGBQUAD));
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
m_bOK = FALSE;
return FALSE;
}
// Fill in the stream header for the text stream....
// The text stream is in 60ths of a second....
/*_fmemset(&m_strhdr, 0, sizeof(m_strhdr));
m_strhdr.fccType = streamtypeTEXT;
m_strhdr.fccHandler = mmioFOURCC('D', 'R', 'A', 'W');
m_strhdr.dwScale = 1;
m_strhdr.dwRate = 60;
m_strhdr.dwSuggestedBufferSize = sizeof(m_szText);
SetRect(&m_strhdr.rcFrame, 0, (int) alpbi->biHeight,
(int) alpbi->biWidth, (int) alpbi->biHeight + TEXT_HEIGHT);
// ....and create the stream.
hr = AVIFileCreateStream(m_pfile, &m_psText, &m_strhdr);
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
m_bOK = FALSE;
return FALSE;
}
m_dwTextFormat = sizeof(m_dwTextFormat);
hr = AVIStreamSetFormat(m_psText, 0, &m_dwTextFormat, sizeof(m_dwTextFormat));
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
m_bOK = FALSE;
return FALSE;
}*/
}
// Jetzt eigentliches Schreiben
hr = AVIStreamWrite(m_psCompressed, // stream pointer
m_nFrame * 10, //10, // time of this frame
1, // number to write
(LPBYTE) alpbi + // pointer to data
alpbi->biSize +
alpbi->biClrUsed * sizeof(RGBQUAD),
alpbi->biSizeImage, // size of this frame
AVIIF_KEYFRAME, // flags....
NULL,
NULL);
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
m_bOK = FALSE;
return FALSE;
}
// Make some text to put in the file ...
//LoadString(hInstance, IDS_TEXTFORMAT, szMessage, BUFSIZE );
/*
strcpy(szMessage, "This is frame #%d");
int iLen = wsprintf(m_szText, szMessage, (int)(m_nFrame + 1));
// ... and write it as well.
hr = AVIStreamWrite(m_psText,
m_nFrame * 40,
1,
m_szText,
iLen + 1,
AVIIF_KEYFRAME,
NULL,
NULL);
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
m_bOK = FALSE;
return FALSE;
}
*/
GlobalFreePtr(alpbi);
m_nFrame++;
return TRUE;
}
//******************************************************//
// 后面的是新添加的函数,前面作了部分修改 //
//******************************************************//
BOOL CAVIFile::AddFrame(XString sBitmapFile)
{
if (!FindFile(sBitmapFile))
return FALSE;
CBitmap bitmap;
if (LoadBMPImage(sBitmapFile,bitmap)) {
AddFrame(bitmap);
}
return TRUE;
}
BOOL CAVIFile::LoadBMPImage(const TCHAR *filename,CBitmap& bitmap)
{
CFile file;
if (!file.Open(filename, CFile::modeRead))
return FALSE;
BITMAPFILEHEADER bmfHeader;
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return FALSE;
if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
return FALSE;
DWORD nPackedDIBLen = file.GetLength() - sizeof(BITMAPFILEHEADER);
HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nPackedDIBLen);
if (hDIB == 0)
return FALSE;
if (file.Read((LPSTR)hDIB, nPackedDIBLen) != nPackedDIBLen){
::GlobalFree(hDIB);
return FALSE;
}
BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed :
1 << bmiHeader.biBitCount;
LPVOID lpDIBBits;
if (bmInfo.bmiHeader.biBitCount > 8) {
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
}
else {
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
}
CClientDC dc(NULL);
HBITMAP hBmp = CreateDIBitmap(dc.m_hDC, // handle to device context
&bmiHeader, // pointer to bitmap size and format data
CBM_INIT, // initialization flag
lpDIBBits, // pointer to initialization data
&bmInfo, // pointer to bitmap color-format data
DIB_RGB_COLORS);// color-data usage
bitmap.Attach(hBmp);
::GlobalFree(hDIB);
return TRUE;
}
void CAVIFile::SetHasSaveOptionsDialog(BOOL bFlag)
{
m_bHasSaveOptionsDialog = bFlag;
}
BOOL CAVIFile::HasSaveOptionsDialog()
{
return m_bHasSaveOptionsDialog;
}
void CAVIFile::SetSaveOptionsParentWnd(HWND hWnd)
{
m_hSaveOptionsParentWnd = hWnd;
}
HWND CAVIFile::GetSaveOptionsParentWnd()
{
return m_hSaveOptionsParentWnd;
}
void CAVIFile::SetColorNum(UINT nColor)
{
m_nColorNum = nColor;
}
UINT CAVIFile::GetColorNum()
{
return m_nColorNum;
}