From 75212086ae886b4a303fa47dc6b412291046d435 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 17 Aug 2009 10:30:28 -0500 Subject: [PATCH] windowscodecs: implement GetFrameCount and GetFrame for the GIF decoder --- dlls/windowscodecs/gifformat.c | 162 +++++++++++++++++++++++++++++++++++++++- 1 files changed, 158 insertions(+), 4 deletions(-) diff --git a/dlls/windowscodecs/gifformat.c b/dlls/windowscodecs/gifformat.c index 77010dd..d236ca3 100644 --- a/dlls/windowscodecs/gifformat.c +++ b/dlls/windowscodecs/gifformat.c @@ -42,6 +42,134 @@ typedef struct { GifFileType *gif; } GifDecoder; +typedef struct { + const IWICBitmapFrameDecodeVtbl *lpVtbl; + LONG ref; + SavedImage *frame; + GifDecoder *parent; +} GifFrameDecode; + +static HRESULT WINAPI GifFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, + void **ppv) +{ + GifFrameDecode *This = (GifFrameDecode*)iface; + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapSource, iid) || + IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) + { + *ppv = This; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI GifFrameDecode_AddRef(IWICBitmapFrameDecode *iface) +{ + GifFrameDecode *This = (GifFrameDecode*)iface; + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI GifFrameDecode_Release(IWICBitmapFrameDecode *iface) +{ + GifFrameDecode *This = (GifFrameDecode*)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + if (ref == 0) + { + IUnknown_Release((IUnknown*)This->parent); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI GifFrameDecode_GetSize(IWICBitmapFrameDecode *iface, + UINT *puiWidth, UINT *puiHeight) +{ + FIXME("(%p,%p,%p): stub\n", iface, puiWidth, puiHeight); + return E_NOTIMPL; +} + +static HRESULT WINAPI GifFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface, + WICPixelFormatGUID *pPixelFormat) +{ + memcpy(pPixelFormat, &GUID_WICPixelFormat8bppIndexed, sizeof(GUID)); + + return S_OK; +} + +static HRESULT WINAPI GifFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, + double *pDpiX, double *pDpiY) +{ + FIXME("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY); + return E_NOTIMPL; +} + +static HRESULT WINAPI GifFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, + IWICPalette *pIPalette) +{ + FIXME("(%p,%p): stub\n", iface, pIPalette); + return E_NOTIMPL; +} + +static HRESULT WINAPI GifFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, + const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) +{ + FIXME("(%p,%p,%u,%u,%p): stub\n", iface, prc, cbStride, cbBufferSize, pbBuffer); + return E_NOTIMPL; +} + +static HRESULT WINAPI GifFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, + IWICMetadataQueryReader **ppIMetadataQueryReader) +{ + TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI GifFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, + UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) +{ + TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI GifFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface, + IWICBitmapSource **ppIThumbnail) +{ + TRACE("(%p,%p)\n", iface, ppIThumbnail); + return WINCODEC_ERR_CODECNOTHUMBNAIL; +} + +static const IWICBitmapFrameDecodeVtbl GifFrameDecode_Vtbl = { + GifFrameDecode_QueryInterface, + GifFrameDecode_AddRef, + GifFrameDecode_Release, + GifFrameDecode_GetSize, + GifFrameDecode_GetPixelFormat, + GifFrameDecode_GetResolution, + GifFrameDecode_CopyPalette, + GifFrameDecode_CopyPixels, + GifFrameDecode_GetMetadataQueryReader, + GifFrameDecode_GetColorContexts, + GifFrameDecode_GetThumbnail +}; + static HRESULT WINAPI GifDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, void **ppv) { @@ -199,15 +327,41 @@ static HRESULT WINAPI GifDecoder_GetThumbnail(IWICBitmapDecoder *iface, static HRESULT WINAPI GifDecoder_GetFrameCount(IWICBitmapDecoder *iface, UINT *pCount) { - FIXME("(%p,%p): stub\n", iface, pCount); - return E_NOTIMPL; + GifDecoder *This = (GifDecoder*)iface; + TRACE("(%p,%p)\n", iface, pCount); + + if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED; + + *pCount = This->gif->ImageCount; + + TRACE("<- %u\n", *pCount); + + return S_OK; } static HRESULT WINAPI GifDecoder_GetFrame(IWICBitmapDecoder *iface, UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) { - FIXME("(%p,%u,%p): stub\n", iface, index, ppIBitmapFrame); - return E_NOTIMPL; + GifDecoder *This = (GifDecoder*)iface; + GifFrameDecode *result; + TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); + + if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED; + + if (index >= This->gif->ImageCount) return E_INVALIDARG; + + result = HeapAlloc(GetProcessHeap(), 0, sizeof(GifFrameDecode)); + if (!result) return E_OUTOFMEMORY; + + result->lpVtbl = &GifFrameDecode_Vtbl; + result->ref = 1; + result->frame = &This->gif->SavedImages[index]; + IWICBitmapDecoder_AddRef(iface); + result->parent = This; + + *ppIBitmapFrame = (IWICBitmapFrameDecode*)result; + + return S_OK; } static const IWICBitmapDecoderVtbl GifDecoder_Vtbl = { -- 1.5.4.3