windows-nt/Source/XPSP1/NT/multimedia/media/avi/drawdib/dva/dva.c
2020-09-26 16:20:57 +08:00

415 lines
10 KiB
C

#include <windows.h>
#define _INC_VFW
#define VFWAPI FAR PASCAL _loadds
#include "dva.h"
#include "lockbm.h"
/****************************************************************************
***************************************************************************/
extern BOOL vga_get_surface(HDC, int, DVASURFACEINFO FAR *);
extern BOOL ati_get_surface(HDC, int, DVASURFACEINFO FAR *);
extern BOOL dib_get_surface(HDC, int, DVASURFACEINFO FAR *);
extern BOOL thun_get_surface(HDC,int, DVASURFACEINFO FAR *);
extern BOOL vlb_get_surface(HDC, int, DVASURFACEINFO FAR *);
#define GetDS() SELECTOROF((LPVOID)&ScreenSel)
static short ScreenSel;
static BOOL InitSurface(DVASURFACEINFO FAR *pdva);
static BOOL TestSurface(DVASURFACEINFO FAR *pdva);
static void SetSelLimit(UINT sel, DWORD limit);
/****************************************************************************
***************************************************************************/
void FAR PASCAL DVAInit()
{
}
/****************************************************************************
***************************************************************************/
void FAR PASCAL DVATerm()
{
//
// free screen alias
//
if (ScreenSel)
{
SetSelLimit(ScreenSel, 0);
FreeSelector(ScreenSel);
ScreenSel = 0;
}
}
/****************************************************************************
***************************************************************************/
BOOL FAR PASCAL _loadds DVAGetSurface(HDC hdc, int nSurface, DVASURFACEINFO FAR *pdva)
{
int i;
i = Escape(hdc, DVAGETSURFACE,sizeof(int),(LPCSTR)&nSurface,(LPVOID)pdva);
//
// should this be a function table? list?
//
if (i <= 0 &&
!dib_get_surface(hdc, nSurface, pdva) &&
!ati_get_surface(hdc, nSurface, pdva) &&
#ifdef DEBUG
!vlb_get_surface(hdc, nSurface, pdva) &&
!thun_get_surface(hdc, nSurface, pdva) &&
#endif
!vga_get_surface(hdc, nSurface, pdva))
return FALSE;
return InitSurface(pdva);
}
#if 0
/****************************************************************************
***************************************************************************/
HDVA FAR PASCAL DVAOpenSurface(HDC hdc, int nSurface)
{
PDVA pdva;
pdva = (PDVA)GlobalAllocPtr(GHND|GMEM_SHARE, sizeof(DVASURFACEINFO));
if (pdva == NULL)
return NULL;
if (!DVAGetSurface(hdc, nSurface, pdva) ||
!pdva->OpenSurface(pdva->lpSurface))
{
GlobalFreePtr(pdva);
return NULL;
}
return pdva;
}
/****************************************************************************
***************************************************************************/
void FAR PASCAL DVACloseSurface(HDVA pdva)
{
if (pdva == NULL)
return;
pdva->CloseSurface(pdva->lpSurface);
GlobalFreePtr(pdva);
}
#endif
/****************************************************************************
***************************************************************************/
BOOL CALLBACK default_open_surface(LPVOID pv)
{
return TRUE;
}
/****************************************************************************
***************************************************************************/
void CALLBACK default_close_surface(LPVOID pv)
{
}
/****************************************************************************
***************************************************************************/
BOOL CALLBACK default_begin_access(LPVOID pv, int x, int y, int dx, int dy)
{
return TRUE;
}
/****************************************************************************
***************************************************************************/
void CALLBACK default_end_access(LPVOID pv)
{
}
/****************************************************************************
***************************************************************************/
UINT CALLBACK default_show_surface(LPVOID pv, HWND hwnd, LPRECT src, LPRECT dst)
{
return 1;
}
/****************************************************************************
***************************************************************************/
static BOOL InitSurface(DVASURFACEINFO FAR *pdva)
{
LPBITMAPINFOHEADER lpbi;
if (pdva->Version != 0x0100)
return FALSE;
lpbi = &pdva->BitmapInfo;
if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
return FALSE;
if (lpbi->biPlanes != 1)
return FALSE;
//
// make the pointer a 16:16 pointer
//
if (pdva->offSurface >= 0x10000 &&
!(pdva->Flags & DVAF_1632_ACCESS))
{
if (ScreenSel == NULL)
ScreenSel = AllocSelector(GetDS());
if (pdva->selSurface != 0)
pdva->offSurface += GetSelectorBase(pdva->selSurface);
SetSelectorBase(ScreenSel,pdva->offSurface);
SetSelLimit(ScreenSel,lpbi->biSizeImage-1);
pdva->offSurface = 0;
pdva->selSurface = ScreenSel;
}
//
// fill in defaults.
//
if (pdva->OpenSurface == NULL)
pdva->OpenSurface = default_open_surface;
if (pdva->CloseSurface == NULL)
pdva->CloseSurface = default_close_surface;
if (pdva->ShowSurface == NULL)
pdva->ShowSurface = default_show_surface;
if (pdva->BeginAccess == NULL)
{
pdva->BeginAccess = default_begin_access;
pdva->EndAccess = default_end_access;
}
//
// only test RGB surfaces.
//
if (lpbi->biCompression == 0 ||
lpbi->biCompression == BI_BITFIELDS ||
lpbi->biCompression == BI_1632)
{
if (!TestSurface(pdva))
return FALSE;
}
//
// set BI_1632 if needed
//
if (pdva->Flags & DVAF_1632_ACCESS)
{
lpbi->biCompression = BI_1632;
}
return TRUE;
}
/****************************************************************************
***************************************************************************/
#pragma optimize("", off)
static void SetSelLimit(UINT sel, DWORD limit)
{
if (limit >= 1024*1024l)
limit = ((limit+4096) & ~4095) - 1;
_asm
{
mov ax,0008h ; DPMI set limit
mov bx,sel
mov dx,word ptr limit[0]
mov cx,word ptr limit[2]
int 31h
}
}
#pragma optimize("", on)
/****************************************************************************
***************************************************************************/
#define ASM66 _asm _emit 0x66 _asm
#define DB _asm _emit
#pragma optimize("", off)
static BYTE ReadByte(PDVA pdva, LPVOID lpBits, DWORD dw)
{
BYTE b=42;
DVABeginAccess(pdva, 0, 0, 1024, 1024);
_asm {
ASM66 xor bx,bx
les bx,lpBits
ASM66 add bx,word ptr dw
mov ax,es
ASM66 lsl ax,ax
ASM66 cmp bx,ax
ja exit
DB 26h ;mov al,es:[ebx]
DB 67h
DB 8Ah
DB 03h
mov b,al
exit:
}
DVAEndAccess(pdva);
return b;
}
#pragma optimize("", on)
/////////////////////////////////////////////////////////////////////////////
//
// SetPixel
//
// some cards cant't seam to do SetPixel right it is amazing they work at all
//
/////////////////////////////////////////////////////////////////////////////
static void SetPixelX(HDC hdc, int x, int y, COLORREF rgb)
{
RECT rc;
rc.left = x;
rc.top = y;
rc.right = x+1;
rc.bottom = y+1;
SetBkColor(hdc, rgb);
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
}
#define SetPixel SetPixelX
/****************************************************************************
***************************************************************************/
static BOOL TestSurface(DVASURFACEINFO FAR *pdva)
{
HDC hdc;
int x,y,h,w,wb;
COLORREF rgb,rgb0,rgb1,rgb2,rgb3,rgb4;
DWORD dw;
BYTE b0,b1;
UINT uType=0;
LPBITMAPINFOHEADER lpbi;
LPVOID lpBits;
HCURSOR hcur;
if (!pdva->OpenSurface(pdva->lpSurface))
return FALSE;
lpbi = DVAGetSurfaceFmt(pdva);
lpBits = DVAGetSurfacePtr(pdva);
h = abs((int)lpbi->biHeight);
w = (int)lpbi->biWidth;
wb = (w * ((UINT)lpbi->biBitCount/8) + 3) & ~3;
dw = (DWORD)(UINT)(h-1) * (DWORD)(UINT)wb;
if ((int)lpbi->biHeight < 0)
y = 0;
else
y = h-1;
#ifdef XDEBUG
x = (int)lpbi->biWidth - 5;
((LPBYTE)lpBits) += x * (UINT)lpbi->biBitCount/8;
#else
x = 0;
#endif
hcur = SetCursor(NULL);
hdc = GetDC(NULL);
rgb = GetPixel(hdc, x, h-1-y);
SetPixel(hdc, x, h-1-y, RGB(0,0,0)); GetPixel(hdc, x, h-1-y); b0 = ReadByte(pdva, lpBits, dw);
SetPixel(hdc, x, h-1-y, RGB(255,255,255)); GetPixel(hdc, x, h-1-y); b1 = ReadByte(pdva, lpBits, dw);
SetPixel(hdc, x, h-1-y,rgb);
if (b0 != 0x00 || b1 == 0x00)
goto done;
rgb0 = GetPixel(hdc, x+0, y);
rgb1 = GetPixel(hdc, x+1, y);
rgb2 = GetPixel(hdc, x+2, y);
rgb3 = GetPixel(hdc, x+3, y);
rgb4 = GetPixel(hdc, x+4, y);
TestSurfaceType(hdc, x, y);
DVABeginAccess(pdva, x, y, 5, 1);
uType = GetSurfaceType(lpBits);
DVAEndAccess(pdva);
SetPixel(hdc, x+0, y,rgb0);
SetPixel(hdc, x+1, y,rgb1);
SetPixel(hdc, x+2, y,rgb2);
SetPixel(hdc, x+3, y,rgb3);
SetPixel(hdc, x+4, y,rgb4);
done:
ReleaseDC(NULL, hdc);
SetCursor(hcur);
pdva->CloseSurface(pdva->lpSurface);
switch (uType)
{
case BM_8BIT:
break;
case BM_16555:
((LPDWORD)(lpbi+1))[0] = 0x007C00;
((LPDWORD)(lpbi+1))[1] = 0x0003E0;
((LPDWORD)(lpbi+1))[2] = 0x00001F;
break;
case BM_24BGR:
case BM_32BGR:
((LPDWORD)(lpbi+1))[0] = 0xFF0000;
((LPDWORD)(lpbi+1))[1] = 0x00FF00;
((LPDWORD)(lpbi+1))[2] = 0x0000FF;
break;
case BM_16565:
lpbi->biCompression = BI_BITFIELDS;
((LPDWORD)(lpbi+1))[0] = 0x00F800;
((LPDWORD)(lpbi+1))[1] = 0x0007E0;
((LPDWORD)(lpbi+1))[2] = 0x00001F;
break;
case BM_24RGB:
case BM_32RGB:
lpbi->biCompression = BI_BITFIELDS;
((LPDWORD)(lpbi+1))[0] = 0x0000FF;
((LPDWORD)(lpbi+1))[1] = 0x00FF00;
((LPDWORD)(lpbi+1))[2] = 0xFF0000;
break;
}
return uType != 0;
}