#include "ddrawpr.h" #include //#include #include "decoder.h" #include #define Assert(x) #define ReleaseMemoryDC(x) DeleteObject(x) #define MulDivQuick MulDiv #define Verify(x) x extern HPALETTE hpalApp; void CImageDecodeEventSink::Init(FILTERINFO * pFilter) { m_nRefCount=0; m_pFilter=pFilter; m_pDDrawSurface=NULL; m_dwLastTick=0; ZeroMemory(&m_rcProg, sizeof(m_rcProg)); } /* CImageDecodeEventSink::~CImageDecodeEventSink() { } */ ULONG CImageDecodeEventSink::AddRef() { m_nRefCount++; return (m_nRefCount); } ULONG CImageDecodeEventSink::Release() { m_nRefCount--; if (m_nRefCount == 0) { // delete this; return (0); } return (m_nRefCount); } STDMETHODIMP CImageDecodeEventSink::QueryInterface(REFIID iid, void** ppInterface) { if (ppInterface == NULL) { return (E_POINTER); } *ppInterface = NULL; if (IsEqualGUID(iid, IID_IUnknown)) { *ppInterface = (IUnknown*)(IImageDecodeEventSink *)this; } else if (IsEqualGUID(iid, IID_IImageDecodeEventSink)) { *ppInterface = (IImageDecodeEventSink*)this; } else { return (E_NOINTERFACE); } // If we're going to return an interface, AddRef it first if (*ppInterface) { ((LPUNKNOWN)*ppInterface)->AddRef(); return S_OK; } return (S_OK); } STDMETHODIMP CImageDecodeEventSink::OnBeginDecode(DWORD* pdwEvents, ULONG* pnFormats, GUID** ppFormats) { GUID* pFormats; if (pdwEvents != NULL) { *pdwEvents = 0; } if (pnFormats != NULL) { *pnFormats = 0; } if (ppFormats != NULL) { *ppFormats = NULL; } if (pdwEvents == NULL) { return (E_POINTER); } if (pnFormats == NULL) { return (E_POINTER); } if (ppFormats == NULL) { return (E_POINTER); } #if 0 if (m_pFilter->_colorMode == 8) { pFormats = (GUID*)CoTaskMemAlloc(1*sizeof(GUID)); if(pFormats == NULL) { return (E_OUTOFMEMORY); } pFormats[0] = BFID_INDEXED_RGB_8; *pnFormats = 1; } #endif #if 1 else { pFormats = (GUID*)CoTaskMemAlloc(2*sizeof(GUID)); if(pFormats == NULL) { return (E_OUTOFMEMORY); } pFormats[0] = BFID_RGB_24; pFormats[1] = BFID_INDEXED_RGB_8; *pnFormats = 2; } #else else { pFormats = (GUID*)CoTaskMemAlloc(1*sizeof(GUID)); if(pFormats == NULL) { return (E_OUTOFMEMORY); } pFormats[0] = BFID_RGB_24; *pnFormats = 1; } #endif *ppFormats = pFormats; *pdwEvents = IMGDECODE_EVENT_PALETTE|IMGDECODE_EVENT_BITSCOMPLETE|IMGDECODE_EVENT_PROGRESS; *pdwEvents |= IMGDECODE_EVENT_USEDDRAW; #if 0 if (m_pFilter->_colorMode != 8) *pdwEvents |= IMGDECODE_EVENT_USEDDRAW; #endif m_dwLastTick = GetTickCount(); return (S_OK); } STDMETHODIMP CImageDecodeEventSink::OnBitsComplete() { return (S_OK); } STDMETHODIMP CImageDecodeEventSink::OnDecodeComplete(HRESULT hrStatus) { return (S_OK); } #define LINEBYTES(_wid,_bits) ((((_wid)*(_bits) + 31) / 32) * 4) STDMETHODIMP CImageDecodeEventSink::GetSurface(LONG nWidth, LONG nHeight, REFGUID bfid, ULONG nPasses, DWORD dwHints, IUnknown** ppSurface) { return GetDDrawSurface(nWidth, nHeight, bfid, nPasses, dwHints, ppSurface); } STDMETHODIMP CImageDecodeEventSink::GetDDrawSurface(LONG nWidth, LONG nHeight, REFGUID bfid, ULONG nPasses, DWORD dwHints, IUnknown ** ppSurface) { DDSURFACEDESC2 ddsd = {sizeof(ddsd)}; (void)nPasses; (void)dwHints; if (ppSurface != NULL) { *ppSurface = NULL; } if (ppSurface == NULL) { return (E_POINTER); } ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; ddsd.dwHeight = nHeight; ddsd.dwWidth = nWidth; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); if (IsEqualGUID(bfid, BFID_INDEXED_RGB_8)) { m_pFilter->m_nBytesPerPixel = 1; ddsd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB; ddsd.ddpfPixelFormat.dwRGBBitCount = 8; ddsd.ddpfPixelFormat.dwRBitMask = 0; ddsd.ddpfPixelFormat.dwGBitMask = 0; ddsd.ddpfPixelFormat.dwBBitMask = 0; ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0; } else if (IsEqualGUID(bfid, BFID_RGB_24)) { m_pFilter->m_nBytesPerPixel = 3; ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; ddsd.ddpfPixelFormat.dwRGBBitCount = 24; ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000L; ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00L; ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FFL; ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0; } else { return (E_NOINTERFACE); } IDirectDrawSurface4 * lpDDS; if (FAILED(m_pDirectDrawEx->CreateSurface(&ddsd, &lpDDS, NULL))) return (E_OUTOFMEMORY); HRESULT hr = lpDDS->QueryInterface(IID_IDirectDrawSurface,(void**)&m_pDDrawSurface); lpDDS->Release(); if (FAILED(hr)) { return hr; } // If this is a palette surface create/attach a palette to it. if (m_pFilter->m_nBytesPerPixel == 1) { PALETTEENTRY ape[256]; LPDIRECTDRAWPALETTE2 pDDPalette; m_pDirectDrawEx->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256, ape, &pDDPalette, NULL); m_pDDrawSurface->SetPalette((LPDIRECTDRAWPALETTE)pDDPalette); pDDPalette->Release(); } m_pFilter->m_pDDrawSurface = m_pDDrawSurface; m_pDDrawSurface->AddRef(); *ppSurface = (IUnknown *)m_pDDrawSurface; (*ppSurface)->AddRef(); return S_OK; } STDMETHODIMP CImageDecodeEventSink::OnPalette() { return (S_OK); } STDMETHODIMP CImageDecodeEventSink::OnProgress(RECT* pBounds, BOOL bComplete) { DWORD dwTick = GetTickCount(); if (pBounds == NULL) { return (E_INVALIDARG); } UnionRect(&m_rcProg, &m_rcProg, pBounds); if (dwTick - m_dwLastTick > 250) { // Used for progressive rendering. Uncomment later // DrawImage(NULL, m_pFilter, &m_rcProg); m_dwLastTick = GetTickCount(); } return (S_OK); }