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

📄 capture.c

📁 超级解霸源代码。纯c语言写的。适合有一定编程基础的开发人员用来学习提高
💻 C
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////////////
//		Capture picture handle
//	      Decode Picture to 24bit BMP file
//		    Southern.Liang
//		       1996.6.25
////////////////////////////////////////////////////////
#pragma	option	-zCOTHER_TEXT
#include <windows.h>
#include <mmsystem.h>
#include <commdlg.h>
#include "DOS.H"
#include "VCDAPI.H"

#define	BEPLAY		8

OPENFILENAME	ofn;
char	DefaultBmpName[]="";
char	DirName[256];
char	FileName[256];
char	FileTitle[256];
char	Filter[]="24Bit RGB Bitmap\0*.BMP\0Double Size 24Bit BMP\0*.BMP\0\
Gray Scale Bitmap\0*.BMP\0NoDither 256Color Bitmap\0*.BMP\0NoDither 256Color \
PCX\0*.PCX\0";
char	BmpTitle[]="Save as Bitmap File";
extern	int	videoID;
extern	HWND	MainWindow;	//Main Windows
extern	HWND	AudioMainWindow;
extern	long	VCDHigh;
extern	HGLOBAL	OffScrSel;
extern	HANDLE 	hInst;
extern	int	Chinese;
BITMAPFILEHEADER	BmpFileHeader=
	{
	0x4D42,		//'BM'
	0,		//Size = SizeImage + 0x36
	0,
	0,
	0x36,		//Offset
	};
BITMAPINFOHEADER	BmpInfoHeader=
	{
	40,	//This struct size
	352,
	240,	//or 288
	1,
	24,	//24bits
	BI_RGB,	//No compress
	0,	//SizeImage = 352 X 240 (or 288) X 3
	0,
	0,
	0,	//Colors used
	0,	//Color Important
	};

static	void	PASCAL	Write24BitBMPHeader(HFILE hFile)
{
	BmpInfoHeader.biSizeImage=352L*VCDHigh*3;
	BmpFileHeader.bfSize=BmpInfoHeader.biSizeImage+0x36;
	BmpInfoHeader.biHeight=VCDHigh;
	BmpInfoHeader.biBitCount=24;
	BmpInfoHeader.biClrUsed=0;
	BmpInfoHeader.biClrImportant=0;
	BmpFileHeader.bfOffBits=0x36;
	/////////////////Write BMP file header /////////////
	_lwrite(hFile,&BmpFileHeader,sizeof(BmpFileHeader));
	_lwrite(hFile,&BmpInfoHeader,sizeof(BmpInfoHeader));
}
typedef	struct	VIDEODATAtag
	{
	DWORD	SelfFlags;	//'STH!'
	DWORD	YPlane;		//Video offset
	DWORD	UPlane;
	DWORD	VPlane;
	DWORD	Selector;	//Video Selector
	DWORD	DataStride;
	DWORD	LineWidth;	//352
	DWORD	LineNumber;	//240 or 288
	}VIDEODATA,FAR *LPVIDEODATA;

static	DWORD	PASCAL	DecodeYUVToRGB24Bits(WORD Selector,DWORD YPlane,
				DWORD UPlane,DWORD VPlane)
{
	int	Y,U,V;
	int	R,G,B;
	//////////// Get Y U V/////////////
	_ES=Selector;
	_EBX=YPlane;
	__emit__(0x26,0x67,0x8A,0x03);//asm	mov	al,es:[ebx]
	Y=_AL;
	_EBX=UPlane;
	__emit__(0x26,0x67,0x8A,0x03);//asm	mov	al,es:[ebx]
	U=_AL;
	_EBX=VPlane;
	__emit__(0x26,0x67,0x8A,0x03);//asm	mov	al,es:[ebx]
	V=_AL;
	//////////// Compute /////////////
	U-=128;V-=128;
	U=359L*U/256;
	V=454L*V/256;
	R=Y+U;
	B=Y+V;
	G=Y-U/2-V/5;
	if(R>255) R=255;
	if(G>255) G=255;
	if(B>255) B=255;
	if(R<0) R=0;
	if(G<0) G=0;
	if(B<0) B=0;
	_DL=B;
	_AH=G;_AL=R;
	return (DWORD)MK_FP(_DX,_AX);
}
HGLOBAL		FilehMem=0;
BYTE far *	FilehMemPtr;
static	void	PASCAL	DecodeCapture24BitPicture(void)
{	//Decode the picture and write to file.
	int		x,y;
	LPVIDEODATA	VideoDataPtr;
	DWORD		Offset=0;

	VideoDataPtr=MK_FP(OffScrSel,0);
	if(VideoDataPtr->SelfFlags!=0x21485453) return;
	if(FilehMem==0) return;
	for(y=0;y<VCDHigh;y++)
		{
		WORD	Selector=VideoDataPtr->Selector;
		DWORD	YPlane=VideoDataPtr->YPlane+0x480L*(VCDHigh-y-1);
		DWORD	UPlane=VideoDataPtr->UPlane+0x480L*(VCDHigh/2-y/2-1);
		DWORD	VPlane=VideoDataPtr->VPlane+0x480L*(VCDHigh/2-y/2-1);
		for(x=0;x<352;x++)
			{
			DecodeYUVToRGB24Bits(Selector,YPlane,UPlane,VPlane);
			_ES=FilehMem;
			_EBX=Offset; 	//DX:AX=RGB 32 bits
			__emit__(0x26,0x67,0x89,0x03);//asm es:[ebx],ax
			__emit__(0x26,0x67,0x88,0x53,0x02);//asm es:[ebx+2],dl
			Offset+=3;
			YPlane++;
			UPlane+=(x&1);
			VPlane+=(x&1);
			}
		}
}
static	void	PASCAL	DecodeCaptureGrayScalePicture(void)
{	//Decode the Gray Scale picture and write to file.
	int		x,y;
	LPVIDEODATA	VideoDataPtr;
	DWORD		Offset=0;

	VideoDataPtr=MK_FP(OffScrSel,0);
	if(VideoDataPtr->SelfFlags!=0x21485453) return;
	if(FilehMem==0) return;
	for(y=0;y<VCDHigh;y++)
		{
		WORD	Selector=VideoDataPtr->Selector;
		DWORD	YPlane=VideoDataPtr->YPlane+0x480L*(VCDHigh-y-1);
		for(x=0;x<352;x++)
			{
			_ES=Selector;
			_EAX=YPlane; 	//AL=Y
			__emit__(0x26,0x67,0x8A,0x00);//asm al,es:[eax]
			_ES=FilehMem;
			_EBX=Offset; 	//AL=Y
			__emit__(0x26,0x67,0x88,0x03);//asm es:[ebx],al
			Offset++;
			YPlane++;
			}
		}
}
int	PictureType=1;
void	PASCAL FAR	DecodeCapturePicture(void)	//API
{	//Decode the picture and write to file.
	switch(PictureType)
		{
		case 1: //24 Bit RGB
		case 2:	//Double Size 24 Bit RGB
		case 4:	//256 Color BMP
		case 5:	//256 Color PCX
			DecodeCapture24BitPicture();
			break;
		case 3:	// Gray Scale
			DecodeCaptureGrayScalePicture();
			break;
		}
}
extern	int	CapturePictureFlags;
static	DWORD	CaptureUpDateVideo(int VideoID,HWND MainWindow)
{
	DWORD	Ret;
	MCI_ANIM_UPDATE_PARMS	mciUpdate;
	HDC	hdc;

	mciUpdate.dwCallback=MainWindow;
	mciUpdate.hDC=0;
	mciUpdate.rc.left=mciUpdate.rc.top=0;
	mciUpdate.rc.right=64;mciUpdate.rc.bottom=56;
	Ret=mciSendCommand(VideoID,MCI_UPDATE,MCI_WAIT|
		MCI_ANIM_RECT,(DWORD)(LPVOID)&mciUpdate);
	if(Ret!=0)
		{
		return	(Ret|0x80000000L);	//FALSE HIWORD Not Zero
		}
	return 1;	//Current Position
}
static	void	PASCAL	Decode24BitsToFile(HFILE hFile)
{
	DWORD	Size=352L*VCDHigh*3;
	FilehMem=GlobalAlloc(GMEM_MOVEABLE,Size);
	if(FilehMem==NULL)
		{
		MessageBox(NULL,"Can't Allocate Error !","Not Enough Memory",MB_ICONSTOP);
		return;
		}
	FilehMemPtr=GlobalLock(FilehMem);
	///////////Start Capture ///////
	CapturePictureFlags=1;
	/////////// Caputre ////////////
	CaptureUpDateVideo(videoID,MainWindow);
	///////////Capture End /////////
	CapturePictureFlags=0;
	////////////// Write /////////////
	_hwrite(hFile,FilehMemPtr,Size);
	//////////////////////////////////
	GlobalUnlock(FilehMem);
	GlobalFree(FilehMem);
}
///////////////////Double Size 24Bit/////////////////////
static	void	PASCAL	WriteD24BitBMPHeader(HFILE hFile)
{
	BmpInfoHeader.biSizeImage=352L*VCDHigh*3*4;
	BmpFileHeader.bfSize=BmpInfoHeader.biSizeImage+0x36;
	BmpInfoHeader.biHeight=VCDHigh*2L;
	BmpInfoHeader.biBitCount=24;
	BmpInfoHeader.biClrUsed=0;
	BmpInfoHeader.biClrImportant=0;
	BmpFileHeader.bfOffBits=0x36;
	BmpInfoHeader.biWidth=352L*2;
	/////////////////Write BMP file header /////////////
	_lwrite(hFile,&BmpFileHeader,sizeof(BmpFileHeader));
	_lwrite(hFile,&BmpInfoHeader,sizeof(BmpInfoHeader));
	BmpInfoHeader.biWidth=352L;
}
static	void	PASCAL	WriteDouble(HFILE hFile,BYTE far * FilehMemPtr)
{
	int		i,j;
	HGLOBAL		hMem;
	BYTE	far	*LocalPtr;
	BYTE	far	*Ptr;
	DWORD		Offset;

	hMem=GlobalAlloc(GMEM_MOVEABLE,4224L);//352L*3*2*2
	LocalPtr=GlobalLock(hMem);
	for(i=0;i<VCDHigh;i++)
		{
		Ptr=LocalPtr;
		Offset=352L*i*3+FP_OFF(FilehMemPtr);
		for(j=0;j<352;j++)
			{
			_ES=FP_SEG(FilehMemPtr);
			_ESI=Offset;
			__emit__(0x26,0x67,0x8B,0x06);//asm 	mov	ax,es:[esi]
			__emit__(0x26,0x67,0x8A,0x56,0x02);//asm     mov	dl,es:[esi+2]
			Offset+=3;
			*(WORD far *)Ptr=_AX;
			*(Ptr+2)=_DL;
			Ptr+=3;
			*(WORD far *)Ptr=_AX;
			*(Ptr+2)=_DL;
			Ptr+=3;
			}
		Offset-=1056L;
		for(j=0;j<352;j++)
			{
			_ES=FP_SEG(FilehMemPtr);
			_ESI=Offset;
			__emit__(0x26,0x67,0x8B,0x06);//asm 	mov	ax,es:[esi]
			__emit__(0x26,0x67,0x8A,0x56,0x02);//asm     mov	dl,es:[esi+2]
			Offset+=3;
			*(WORD far *)Ptr=_AX;
			*(Ptr+2)=_DL;
			Ptr+=3;
			*(WORD far *)Ptr=_AX;
			*(Ptr+2)=_DL;
			Ptr+=3;
			}
		_lwrite(hFile,LocalPtr,4224L);//write 2 lines
		}
	GlobalUnlock(hMem);
	GlobalFree(hMem);
}
static	void	PASCAL	DecodeD24BitsToFile(HFILE hFile)
{
	DWORD	Size=352L*VCDHigh*3;
	FilehMem=GlobalAlloc(GMEM_MOVEABLE,Size);
	if(FilehMem==NULL)
		{
		MessageBox(NULL,"Can't Allocate Error !","Not Enough Memory",MB_ICONSTOP);
		return;
		}
	FilehMemPtr=GlobalLock(FilehMem);
	///////////Start Capture ///////
	CapturePictureFlags=1;
	/////////// Caputre ////////////
	CaptureUpDateVideo(videoID,MainWindow);
	///////////Capture End /////////
	CapturePictureFlags=0;
	////////////// Write /////////////
	WriteDouble(hFile,FilehMemPtr);
	//////////////////////////////////
	GlobalUnlock(FilehMem);
	GlobalFree(FilehMem);
}

///////////////////Gray Scale ///////////////////////////
static	void	PASCAL	Write8BitBMPHeader(HFILE hFile)
{
	BmpInfoHeader.biSizeImage=352L*VCDHigh;
	BmpFileHeader.bfSize=BmpInfoHeader.biSizeImage+0x436;
	BmpInfoHeader.biHeight=VCDHigh;
	BmpInfoHeader.biBitCount=8;
	BmpInfoHeader.biClrUsed=256;
	BmpInfoHeader.biClrImportant=256;
	BmpFileHeader.bfOffBits=0x436;		//BMP Data Offset
	/////////////////Write BMP file header /////////////
	_lwrite(hFile,&BmpFileHeader,sizeof(BmpFileHeader));
	_lwrite(hFile,&BmpInfoHeader,sizeof(BmpInfoHeader));
}
static	int	PASCAL	WriteGrayScalePalette(HFILE hFile)
{
	int	i;
	FilehMem=GlobalAlloc(GMEM_MOVEABLE,0x400);//256 * 4
	if(FilehMem==NULL) return 0;
	FilehMemPtr=GlobalLock(FilehMem);
	for(i=0;i<256;i++)
		{
		*(FilehMemPtr+i*4)  =
		*(FilehMemPtr+i*4+1)=
		*(FilehMemPtr+i*4+2)=i;
		*(FilehMemPtr+i*4+3)=0;
		}
	_lwrite(hFile,FilehMemPtr,0x400);
	GlobalUnlock(FilehMem);
	GlobalFree(FilehMem);
	return 1;
}
static	void	PASCAL	Decode8BitsGrayScaleToFile(HFILE hFile)
{
	DWORD	Size=352L*VCDHigh;

	if(WriteGrayScalePalette(hFile)==0)	//Write Palette
		{
		MessageBox(NULL,"Can't Allocate Error !","Not Enough Memory",MB_ICONSTOP);
		return;
		}
	//////////// Decode a Y picture ////////
	FilehMem=GlobalAlloc(GMEM_MOVEABLE,Size);
	if(FilehMem==NULL)
		{
		MessageBox(NULL,"Can't Allocate Error !","Not Enough Memory",MB_ICONSTOP);
		return;
		}
	FilehMemPtr=GlobalLock(FilehMem);
	///////////Start Capture ///////
	CapturePictureFlags=1;
	/////////// Caputre ////////////
	CaptureUpDateVideo(videoID,MainWindow);
	///////////Capture End /////////
	CapturePictureFlags=0;
	////////////// Write /////////////
	_hwrite(hFile,FilehMemPtr,Size);
	//////////////////////////////////
	GlobalUnlock(FilehMem);
	GlobalFree(FilehMem);
}
static	void	PASCAL	Decode24BitsToMemory(void)
{
	DWORD	Size=352L*VCDHigh*3;
	FilehMem=GlobalAlloc(GMEM_MOVEABLE,Size);
	if(FilehMem==NULL)
		{
		MessageBox(NULL,"Can't Allocate Error !","Not Enough Memory",MB_ICONSTOP);
		return;
		}
	FilehMemPtr=GlobalLock(FilehMem);
	///////////Start Capture ///////
	CapturePictureFlags=1;
	/////////// Caputre ////////////
	CaptureUpDateVideo(videoID,MainWindow);
	///////////Capture End /////////
	CapturePictureFlags=0;
	GlobalUnlock(FilehMem);
}
HGLOBAL	Bmp256CMem;
HGLOBAL	Bmp256CPalMem;
static	int	Allocate256ColorMemory(void)
{
	Bmp256CMem=GlobalAlloc(GMEM_MOVEABLE,352L*VCDHigh);
	if(Bmp256CMem==NULL)	return 0;
	Bmp256CPalMem=GlobalAlloc(GMEM_MOVEABLE,0x400+sizeof(BITMAPINFOHEADER));//256 * 4 + sizeof(BITMAPINFOHEADER)
	if(Bmp256CPalMem==NULL)
		{
		GlobalFree(Bmp256CMem);
		return 0;
		}
	return 1;
}
static	void	FreeAllMemory(void)
{	//Free all memory when complete.
	GlobalFree(Bmp256CMem);
	GlobalFree(Bmp256CPalMem);
	GlobalFree(FilehMem);
}
LPRGBQUAD	PalPtr;
int	PalCount=0;
int	Default=6;
/***************************\
int	SearchLong(BYTE R,BYTE G,BYTE B)
{
	int	i;
	int	Long=256;
	int	Length;
	int	Pal=0;
	int	r,g,b;

	for(i=0;i<PalCount;i++)
		{//Search The short disance
		b=PalPtr[i].rgbBlue-R;
		g=PalPtr[i].rgbGreen-G;
		r=PalPtr[i].rgbRed-B;
		Length=abs(r)+abs(g)+abs(b);
		if(Length<Long)
			{
			Long=Length;
			Pal=i;	//Remember the short Palette
			}
		}
	if(Long>Default && PalCount<256)//New a Palette
		{
		PalPtr[PalCount].rgbReserved	=0;
		PalPtr[PalCount].rgbBlue	=B;
		PalPtr[PalCount].rgbGreen	=G;
		PalPtr[PalCount].rgbRed		=R;
		Pal=PalCount;
		PalCount++;
		}
	return Pal;
}
\***********************************/
static	int	SearchLong(void)
{	//DX:AX=RGB
	int	i;
	int	Long=256;
	int	Length;
	int	Pal=0;
	DWORD	RGB;
	DWORD	rgb;
	DWORD far *	Ptr;

	asm	xor	dh,dh
	asm	mov 	word ptr RGB,ax	//remember RGB
	asm	mov	word ptr RGB+2,dx
	Ptr=(DWORD far *)PalPtr;
	for(i=0;i<PalCount;i++)
		{//Search The short disance
		rgb=*Ptr++;
		asm	mov  	ax,word ptr rgb
		asm	mov	dx,word ptr rgb+2
		asm	sub	al,byte ptr RGB
		asm	sub	ah,byte ptr RGB+1
		asm	sub	dl,byte ptr RGB+2
		if(_AL>=0x3F) asm 	neg	al;
		if(_AH>=0x3F) asm	neg	ah;
		if(_DL>=0x3F) asm	neg	dl;
		asm	add	al,ah
		asm	mov	ah,dh
		asm	add	ax,dx
		if(_AX<Long)
			{
			if(_AX<=Default) return i;
			Long=_AX;
			Pal=i;	//Remember the short Palette
			}
		}
	if(Long>Default && PalCount<256)//New a Palette
		{
		*Ptr=RGB;
		Pal=PalCount;
		PalCount++;
		}
	return Pal;
}
static	void	PaletteNormal(void)
{
	int	i;
	for(i=0;i<256;i++)

⌨️ 快捷键说明

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