Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

297 lines
6.5 KiB

#include "ddrawpr.h"
#include <ImgUtil.H>
//#include <ocmm.h>
#include "decoder.h"
#include <atlcom.h>
#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);
}