|
|
#include "stdafx.h"
#include "imgutil.h"
#include "ddraw.h"
#include "cddsurf.h"
// Get rid of "synonyms" warning
#pragma warning(disable : 4097)
// Get rid of "unused formal parameters warning"
#pragma warning(disable : 4100)
#undef DEFINE_GUID
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
EXTERN_C const GUID name \ = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
DEFINE_GUID( IID_IDirectDrawSurface, 0x6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00, 0x20,0xAF,0x0B,0xE5,0x60 );
DEFINE_GUID( IID_IDirectDrawPalette, 0x6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00, 0x20,0xAF,0x0B,0xE5,0x60 );
const RGBQUAD g_rgbBgColor = { 0xFF, 0xFF, 0xFF, 0 }; const RGBQUAD g_rgbFgColor = { 0x00, 0x00, 0x00, 0 };
const PALETTEENTRY g_peVga[16] = { { 0x00, 0x00, 0x00, 0x00 }, // Black
{ 0x80, 0x00, 0x00, 0x00 }, // Dark red
{ 0x00, 0x80, 0x00, 0x00 }, // Dark green
{ 0x80, 0x80, 0x00, 0x00 }, // Dark yellow
{ 0x00, 0x00, 0x80, 0x00 }, // Dark blue
{ 0x80, 0x00, 0x80, 0x00 }, // Dark purple
{ 0x00, 0x80, 0x80, 0x00 }, // Dark aqua
{ 0xC0, 0xC0, 0xC0, 0x00 }, // Light grey
{ 0x80, 0x80, 0x80, 0x00 }, // Dark grey
{ 0xFF, 0x00, 0x00, 0x00 }, // Light red
{ 0x00, 0xFF, 0x00, 0x00 }, // Light green
{ 0xFF, 0xFF, 0x00, 0x00 }, // Light yellow
{ 0x00, 0x00, 0xFF, 0x00 }, // Light blue
{ 0xFF, 0x00, 0xFF, 0x00 }, // Light purple
{ 0x00, 0xFF, 0xFF, 0x00 }, // Light aqua
{ 0xFF, 0xFF, 0xFF, 0x00 } // White
};
#define Verify(x) (x)
LONG g_lSecondaryObjCount = 0;
#define DecrementSecondaryObjectCount( idCaller ) DecrementSecondaryObjectCount_Actual()
inline void DecrementSecondaryObjectCount_Actual() { InterlockedDecrement(&g_lSecondaryObjCount); }
#define IncrementSecondaryObjectCount( idCaller ) IncrementSecondaryObjectCount_Actual()
inline void IncrementSecondaryObjectCount_Actual() { Verify(InterlockedIncrement(&g_lSecondaryObjCount) > 0); }
CBaseFT::CBaseFT(CRITICAL_SECTION * pcs) { _ulRefs = 1; _ulAllRefs = 1; _pcs = pcs; IncrementSecondaryObjectCount(10); }
CBaseFT::~CBaseFT() { DecrementSecondaryObjectCount(10); }
void CBaseFT::Passivate() { }
ULONG CBaseFT::Release() { ULONG ulRefs = (ULONG)InterlockedDecrement((LONG *)&_ulRefs);
if (ulRefs == 0) { Passivate(); SubRelease(); }
return(ulRefs); }
ULONG CBaseFT::SubRelease() { ULONG ulRefs = (ULONG)InterlockedDecrement((LONG *)&_ulAllRefs);
if (ulRefs == 0) { delete this; }
return(ulRefs); }
void CopyColorsFromPaletteEntries(RGBQUAD *prgb, const PALETTEENTRY *ppe, UINT uCount) { while (uCount--) { prgb->rgbRed = ppe->peRed; prgb->rgbGreen = ppe->peGreen; prgb->rgbBlue = ppe->peBlue; prgb->rgbReserved = 0;
prgb++; ppe++; } }
void CopyPaletteEntriesFromColors(PALETTEENTRY *ppe, const RGBQUAD *prgb, UINT uCount) { while (uCount--) { ppe->peRed = prgb->rgbRed; ppe->peGreen = prgb->rgbGreen; ppe->peBlue = prgb->rgbBlue; ppe->peFlags = 0;
prgb++; ppe++; } }
#define MASK565_0 0x0000F800
#define MASK565_1 0x000007E0
#define MASK565_2 0x0000001F
HBITMAP ImgCreateDib(LONG xWid, LONG yHei, BOOL fPal, int cBitsPerPix, int cEnt, PALETTEENTRY * ppe, BYTE ** ppbBits, int * pcbRow) { struct { BITMAPINFOHEADER bmih; union { RGBQUAD argb[256]; WORD aw[256]; DWORD adw[3]; } u; } bmi; int i;
if (cBitsPerPix != 8) fPal = FALSE;
bmi.bmih.biSize = sizeof(BITMAPINFOHEADER); bmi.bmih.biWidth = xWid; bmi.bmih.biHeight = yHei; bmi.bmih.biPlanes = 1; bmi.bmih.biBitCount = (WORD)((cBitsPerPix == 15) ? 16 : cBitsPerPix); bmi.bmih.biCompression = (cBitsPerPix == 16) ? BI_BITFIELDS : BI_RGB; bmi.bmih.biSizeImage = 0; bmi.bmih.biXPelsPerMeter = 0; bmi.bmih.biYPelsPerMeter = 0; bmi.bmih.biClrUsed = 0; bmi.bmih.biClrImportant = 0;
if (cBitsPerPix == 1) { bmi.bmih.biClrUsed = 2;
if (cEnt > 2) cEnt = 2;
if (cEnt > 0) { bmi.bmih.biClrImportant = cEnt; CopyColorsFromPaletteEntries(bmi.u.argb, ppe, cEnt); } else { bmi.u.argb[0] = g_rgbBgColor; bmi.u.argb[1] = g_rgbFgColor; } } else if (cBitsPerPix == 4) { bmi.bmih.biClrUsed = 16;
if (cEnt > 16) cEnt = 16;
if (cEnt > 0) { bmi.bmih.biClrImportant = cEnt; CopyColorsFromPaletteEntries(bmi.u.argb, ppe, cEnt); } else { bmi.bmih.biClrImportant = 16; CopyColorsFromPaletteEntries(bmi.u.argb, g_peVga, 16); } } else if (cBitsPerPix == 8) { if (fPal) { bmi.bmih.biClrUsed = 256;
for (i = 0; i < 256; ++i) bmi.u.aw[i] = (WORD)i; } else { if (cEnt > 0 && cEnt < 256) { bmi.bmih.biClrUsed = cEnt; bmi.bmih.biClrImportant = cEnt; } else bmi.bmih.biClrUsed = 256;
if (cEnt && ppe) { CopyColorsFromPaletteEntries(bmi.u.argb, ppe, cEnt); } } } else if (cBitsPerPix == 16) { bmi.u.adw[0] = MASK565_0; bmi.u.adw[1] = MASK565_1; bmi.u.adw[2] = MASK565_2; }
return ImgCreateDibFromInfo((BITMAPINFO *)&bmi, fPal ? DIB_PAL_COLORS : DIB_RGB_COLORS, ppbBits, pcbRow); }
HBITMAP ImgCreateDibFromInfo(BITMAPINFO * pbmi, UINT wUsage, BYTE ** ppbBits, int * pcbRow) { HDC hdcMem = NULL; HBITMAP hbm = NULL; BYTE * pbBits; int cbRow; LONG xWid, yHei; int cBitsPerPix;
xWid = pbmi->bmiHeader.biWidth; yHei = pbmi->bmiHeader.biHeight; cBitsPerPix = pbmi->bmiHeader.biBitCount; cbRow = ((xWid * cBitsPerPix + 31) & ~31) / 8;
if (pcbRow) { *pcbRow = cbRow; }
hdcMem = CreateCompatibleDC(NULL);
if (hdcMem == NULL) goto Cleanup;
hbm = CreateDIBSection(hdcMem, pbmi, wUsage, (void **)&pbBits, NULL, 0);
if (hbm && ppbBits) { *ppbBits = pbBits; }
Cleanup: if (hdcMem) DeleteDC(hdcMem);
return(hbm); }
CDDrawWrapper::CDDrawWrapper(HBITMAP hbmDib) { m_hbmDib = hbmDib; GetObject(hbmDib, sizeof(DIBSECTION), &m_dsSurface); m_lPitch = ((m_dsSurface.dsBmih.biWidth * m_dsSurface.dsBmih.biBitCount + 31) & ~31) / 8; if (m_dsSurface.dsBmih.biHeight > 0) { m_pbBits = (BYTE *)m_dsSurface.dsBm.bmBits + (m_dsSurface.dsBm.bmHeight - 1) * m_lPitch; m_lPitch = -m_lPitch; } else { m_pbBits = (BYTE *)m_dsSurface.dsBm.bmBits; }
// left, top already 0
m_rcSurface.right = m_dsSurface.dsBm.bmWidth; m_rcSurface.bottom = m_dsSurface.dsBm.bmHeight;
// initialize transparent index to -1
m_ddColorKey.dwColorSpaceLowValue = m_ddColorKey.dwColorSpaceHighValue = (DWORD)-1; }
CDDrawWrapper::~CDDrawWrapper() { }
STDMETHODIMP CDDrawWrapper::QueryInterface(REFIID riid, void ** ppv) { if (riid == IID_IDirectDrawSurface) *ppv = (IUnknown *)(IDirectDrawSurface *)this; else if (riid == IID_IDirectDrawPalette) *ppv = (IUnknown *)(IDirectDrawPalette *)this; else if (riid == IID_IUnknown) *ppv = (IUnknown *)(IDirectDrawSurface *)this; else *ppv = NULL;
if (*ppv) { ((LPUNKNOWN)*ppv)->AddRef(); return(S_OK); } else { return(E_NOINTERFACE); } }
STDMETHODIMP_(ULONG) CDDrawWrapper::AddRef() { return(super::AddRef()); }
STDMETHODIMP_(ULONG) CDDrawWrapper::Release() { return(super::Release()); }
STDMETHODIMP CDDrawWrapper::GetColorKey(DWORD dw, LPDDCOLORKEY lpKey) { if (dw != DDCKEY_SRCBLT) return E_INVALIDARG;
if (lpKey == NULL) return E_POINTER;
memcpy(lpKey, &m_ddColorKey, sizeof(DDCOLORKEY));
return S_OK; }
STDMETHODIMP CDDrawWrapper::GetPalette(LPDIRECTDRAWPALETTE FAR* ppPal) { if (ppPal == NULL) return E_POINTER; // Return interface to set color table if DIB section has one
if (m_dsSurface.dsBmih.biBitCount <= 8) { *ppPal = (LPDIRECTDRAWPALETTE)this; ((LPUNKNOWN)*ppPal)->AddRef(); return S_OK; } else { *ppPal = NULL; return E_NOINTERFACE; } }
STDMETHODIMP CDDrawWrapper::SetColorKey(DWORD dwFlags, LPDDCOLORKEY pDDColorKey) { if (dwFlags != DDCKEY_SRCBLT) return E_INVALIDARG;
if (pDDColorKey == NULL) return E_POINTER;
memcpy(&m_ddColorKey, pDDColorKey, sizeof(DDCOLORKEY));
return S_OK; }
STDMETHODIMP CDDrawWrapper::SetEntries(DWORD dwFlags, DWORD dwStart, DWORD dwCount, LPPALETTEENTRY pEntries) { RGBQUAD argb[256]; DWORD nColors = (DWORD)(1 << m_dsSurface.dsBmih.biBitCount); UINT nColorsSet; HDC hdc; HBITMAP hbm; if (dwFlags) return E_INVALIDARG;
if (dwStart >= nColors || dwStart + dwCount > nColors) return E_INVALIDARG;
if (pEntries == NULL) return E_POINTER;
CopyColorsFromPaletteEntries(argb, pEntries, dwCount); hdc = CreateCompatibleDC(NULL); if (hdc) { hbm = (HBITMAP)SelectObject(hdc, m_hbmDib); nColorsSet = SetDIBColorTable(hdc, (UINT)dwStart, (UINT)dwCount, argb); SelectObject(hdc, hbm); DeleteDC(hdc); } else nColorsSet = 0; return nColorsSet ? S_OK : E_FAIL; }
STDMETHODIMP CDDrawWrapper::GetEntries(DWORD dwFlags, DWORD dwStart, DWORD dwCount, LPPALETTEENTRY pEntries) { RGBQUAD argb[256]; DWORD nColors = (DWORD)(1 << m_dsSurface.dsBmih.biBitCount); UINT nColorsGet; HDC hdc; HBITMAP hbm; if (dwFlags) return E_INVALIDARG;
if (dwStart >= nColors || dwStart + dwCount > nColors) return E_INVALIDARG;
if (pEntries == NULL) return E_POINTER;
hdc = CreateCompatibleDC(NULL); if (hdc) { hbm = (HBITMAP)SelectObject(hdc, m_hbmDib); nColorsGet = GetDIBColorTable(hdc, (UINT)dwStart, (UINT)dwCount, argb); SelectObject(hdc, hbm); DeleteDC(hdc); } else return E_FAIL;
if (nColorsGet) CopyPaletteEntriesFromColors(pEntries, argb, dwCount);
return nColorsGet ? S_OK : E_FAIL; }
STDMETHODIMP CDDrawWrapper::Lock(LPRECT pRect, LPDDSURFACEDESC pSurfaceDesc, DWORD dwFlags, HANDLE hEvent) { RECT rcClip; if (pRect == NULL || pSurfaceDesc == NULL) return E_POINTER;
if (pSurfaceDesc->dwSize != sizeof(DDSURFACEDESC)) return E_INVALIDARG;
if (hEvent) return E_INVALIDARG;
IntersectRect(&rcClip, pRect, &m_rcSurface); if (!EqualRect(&rcClip, pRect)) return E_INVALIDARG; pSurfaceDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH; pSurfaceDesc->dwWidth = m_dsSurface.dsBm.bmWidth; pSurfaceDesc->dwHeight = m_dsSurface.dsBm.bmHeight; pSurfaceDesc->lPitch = m_lPitch;
pSurfaceDesc->lpSurface = (LPVOID)(m_pbBits + pRect->top * m_lPitch + ((pRect->left * m_dsSurface.dsBmih.biBitCount) / 8)); return S_OK; }
STDMETHODIMP CDDrawWrapper::Unlock(LPVOID pBits) { return S_OK; }
// The remainder of these methods are not needed by the plugin filters
STDMETHODIMP CDDrawWrapper::AddAttachedSurface(LPDIRECTDRAWSURFACE lpdds) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::AddOverlayDirtyRect(LPRECT lprc) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::Blt(LPRECT lprcDest, LPDIRECTDRAWSURFACE lpdds, LPRECT lprcSrc, DWORD dw, LPDDBLTFX lpfx) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::BltBatch(LPDDBLTBATCH lpBlt, DWORD dwCount, DWORD dwFlags) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpdds, LPRECT lprcSrc, DWORD dwTrans) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::DeleteAttachedSurface(DWORD dwFlags, LPDIRECTDRAWSURFACE lpdds) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::EnumAttachedSurfaces(LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfn) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::EnumOverlayZOrders(DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfn) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::Flip(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::GetAttachedSurface(LPDDSCAPS lpCaps, LPDIRECTDRAWSURFACE FAR * lpdds) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::GetBltStatus(DWORD dw) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::GetCaps(LPDDSCAPS lpCaps) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::GetClipper(LPDIRECTDRAWCLIPPER FAR* lpClipper) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::GetDC(HDC FAR * lphdc) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::GetFlipStatus(DWORD dw) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::GetOverlayPosition(LPLONG lpl1, LPLONG lpl2) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::GetPixelFormat(LPDDPIXELFORMAT pPixelFormat) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::GetSurfaceDesc(LPDDSURFACEDESC pSurfaceDesc) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::Initialize(LPDIRECTDRAW pDD, LPDDSURFACEDESC pSurfaceDesc) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::IsLost() { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::ReleaseDC(HDC hdc) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::Restore() { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::SetClipper(LPDIRECTDRAWCLIPPER pClipper) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::SetOverlayPosition(LONG x, LONG y) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::SetPalette(LPDIRECTDRAWPALETTE pDDPal) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::UpdateOverlay(LPRECT prc, LPDIRECTDRAWSURFACE pdds, LPRECT prc2, DWORD dw, LPDDOVERLAYFX pfx) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::UpdateOverlayDisplay(DWORD dw) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::UpdateOverlayZOrder(DWORD dw, LPDIRECTDRAWSURFACE pdds) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::GetCaps(LPDWORD lpdw) { return E_NOTIMPL; }
STDMETHODIMP CDDrawWrapper::Initialize(LPDIRECTDRAW lpdd, DWORD dwCount, LPPALETTEENTRY pEntries) { return E_NOTIMPL; }
|