From 9e81463de9af736ed53efb4abb57c75e60caaed8 Mon Sep 17 00:00:00 2001 From: Ziqing Hui Date: Wed, 15 Apr 2020 18:42:07 +0800 Subject: [PATCH] windowscodecs: Implement stub for DdsDecoder. Signed-off-by: Ziqing Hui Signed-off-by: Vincent Povirk Signed-off-by: Alexandre Julliard --- dlls/windowscodecs/Makefile.in | 1 + dlls/windowscodecs/clsfactory.c | 1 + dlls/windowscodecs/ddsformat.c | 227 ++++++++++++++++++ dlls/windowscodecs/regsvr.c | 23 ++ dlls/windowscodecs/tests/ddsformat.c | 4 +- dlls/windowscodecs/wincodecs_private.h | 1 + dlls/windowscodecs/windowscodecs_wincodec.idl | 7 + 7 files changed, 262 insertions(+), 2 deletions(-) create mode 100644 dlls/windowscodecs/ddsformat.c diff --git a/dlls/windowscodecs/Makefile.in b/dlls/windowscodecs/Makefile.in index 3505e804ca7..37ac771c8f1 100644 --- a/dlls/windowscodecs/Makefile.in +++ b/dlls/windowscodecs/Makefile.in @@ -13,6 +13,7 @@ C_SRCS = \ colorcontext.c \ colortransform.c \ converter.c \ + ddsformat.c \ fliprotate.c \ gifformat.c \ icnsformat.c \ diff --git a/dlls/windowscodecs/clsfactory.c b/dlls/windowscodecs/clsfactory.c index 32083a2a3f4..2a0d26352d4 100644 --- a/dlls/windowscodecs/clsfactory.c +++ b/dlls/windowscodecs/clsfactory.c @@ -56,6 +56,7 @@ static const classinfo wic_classes[] = { {&CLSID_WICTiffDecoder, TiffDecoder_CreateInstance}, {&CLSID_WICTiffEncoder, TiffEncoder_CreateInstance}, {&CLSID_WICIcnsEncoder, IcnsEncoder_CreateInstance}, + {&CLSID_WICDdsDecoder, DdsDecoder_CreateInstance}, {&CLSID_WICDefaultFormatConverter, FormatConverter_CreateInstance}, {&CLSID_WineTgaDecoder, TgaDecoder_CreateInstance}, {&CLSID_WICUnknownMetadataReader, UnknownMetadataReader_CreateInstance}, diff --git a/dlls/windowscodecs/ddsformat.c b/dlls/windowscodecs/ddsformat.c new file mode 100644 index 00000000000..67680e9a0a3 --- /dev/null +++ b/dlls/windowscodecs/ddsformat.c @@ -0,0 +1,227 @@ +/* + * Copyright 2020 Ziqing Hui + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +typedef struct DdsDecoder { + IWICBitmapDecoder IWICBitmapDecoder_iface; + LONG ref; + BOOL initialized; + IStream *stream; + CRITICAL_SECTION lock; +} DdsDecoder; + +static inline DdsDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) +{ + return CONTAINING_RECORD(iface, DdsDecoder, IWICBitmapDecoder_iface); +} + +static HRESULT WINAPI DdsDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, + void **ppv) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapDecoder, iid)) + { + *ppv = &This->IWICBitmapDecoder_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI DdsDecoder_AddRef(IWICBitmapDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI DdsDecoder_Release(IWICBitmapDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + if (ref == 0) + { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); + if (This->stream) IStream_Release(This->stream); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI DdsDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, + DWORD *capability) +{ + FIXME("(%p,%p,%p): stub.\n", iface, stream, capability); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, + WICDecodeOptions cacheOptions) +{ + FIXME("(%p,%p,%x): stub.\n", iface, pIStream, cacheOptions); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_GetContainerFormat(IWICBitmapDecoder *iface, + GUID *pguidContainerFormat) +{ + memcpy(pguidContainerFormat, &GUID_ContainerFormatDds, sizeof(GUID)); + return S_OK; +} + +static HRESULT WINAPI DdsDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, + IWICBitmapDecoderInfo **ppIDecoderInfo) +{ + FIXME("(%p,%p): stub.\n", iface, ppIDecoderInfo); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_CopyPalette(IWICBitmapDecoder *iface, + IWICPalette *pIPalette) +{ + FIXME("(%p,%p): stub.\n", iface, pIPalette); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, + IWICMetadataQueryReader **ppIMetadataQueryReader) +{ + FIXME("(%p,%p): stub.\n", iface, ppIMetadataQueryReader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_GetPreview(IWICBitmapDecoder *iface, + IWICBitmapSource **ppIBitmapSource) +{ + FIXME("(%p,%p): stub.\n", iface, ppIBitmapSource); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_GetColorContexts(IWICBitmapDecoder *iface, + UINT cCount, IWICColorContext **ppDdslorContexts, UINT *pcActualCount) +{ + FIXME("(%p,%u,%p,%p): stub.\n", iface, cCount, ppDdslorContexts, pcActualCount); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_GetThumbnail(IWICBitmapDecoder *iface, + IWICBitmapSource **ppIThumbnail) +{ + FIXME("(%p,%p): stub.\n", iface, ppIThumbnail); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_GetFrameCount(IWICBitmapDecoder *iface, + UINT *pCount) +{ + FIXME("(%p) <-- %d: stub.\n", iface, *pCount); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_GetFrame(IWICBitmapDecoder *iface, + UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) +{ + FIXME("(%p,%u,%p): stub.\n", iface, index, ppIBitmapFrame); + + return E_NOTIMPL; +} + +static const IWICBitmapDecoderVtbl DdsDecoder_Vtbl = { + DdsDecoder_QueryInterface, + DdsDecoder_AddRef, + DdsDecoder_Release, + DdsDecoder_QueryCapability, + DdsDecoder_Initialize, + DdsDecoder_GetContainerFormat, + DdsDecoder_GetDecoderInfo, + DdsDecoder_CopyPalette, + DdsDecoder_GetMetadataQueryReader, + DdsDecoder_GetPreview, + DdsDecoder_GetColorContexts, + DdsDecoder_GetThumbnail, + DdsDecoder_GetFrameCount, + DdsDecoder_GetFrame +}; + +HRESULT DdsDecoder_CreateInstance(REFIID iid, void** ppv) +{ + DdsDecoder *This; + HRESULT ret; + + TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); + + *ppv = NULL; + + This = HeapAlloc(GetProcessHeap(), 0, sizeof(DdsDecoder)); + if (!This) return E_OUTOFMEMORY; + + This->IWICBitmapDecoder_iface.lpVtbl = &DdsDecoder_Vtbl; + This->ref = 1; + This->initialized = FALSE; + This->stream = NULL; + InitializeCriticalSection(&This->lock); + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DdsDecoder.lock"); + + ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); + IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); + + return ret; +} diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c index d215e308083..2c053bc5e4a 100644 --- a/dlls/windowscodecs/regsvr.c +++ b/dlls/windowscodecs/regsvr.c @@ -1140,6 +1140,18 @@ static struct decoder_pattern const bmp_patterns[] = { {0} }; +static const BYTE dds_magic[] = "DDS "; + +static GUID const * const dds_formats[] = { + &GUID_WICPixelFormat32bppBGRA, + NULL +}; + +static struct decoder_pattern const dds_patterns[] = { + {4,0,dds_magic,mask_all,0}, + {0} +}; + static const BYTE gif87a_magic[6] = "GIF87a"; static const BYTE gif89a_magic[6] = "GIF89a"; @@ -1273,6 +1285,17 @@ static struct regsvr_decoder const decoder_list[] = { bmp_formats, bmp_patterns }, + { &CLSID_WICDdsDecoder, + "The Wine Project", + "DDS Decoder", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_ContainerFormatDds, + "image/vnd-ms.dds", + ".dds", + dds_formats, + dds_patterns + }, { &CLSID_WICGifDecoder, "The Wine Project", "GIF Decoder", diff --git a/dlls/windowscodecs/tests/ddsformat.c b/dlls/windowscodecs/tests/ddsformat.c index 97fb9f7c113..6df303d8ff6 100644 --- a/dlls/windowscodecs/tests/ddsformat.c +++ b/dlls/windowscodecs/tests/ddsformat.c @@ -78,7 +78,7 @@ static IWICBitmapDecoder *create_decoder(IWICStream *stream) ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatDds), "Unexpected container format\n"); hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)stream, WICDecodeMetadataCacheOnDemand); - ok(hr == S_OK, "Decoder Initialize failed, hr=%x\n", hr); + todo_wine ok(hr == S_OK, "Decoder Initialize failed, hr=%x\n", hr); if (hr != S_OK) { IWICBitmapDecoder_Release(decoder); return NULL; @@ -95,7 +95,7 @@ static void test_dds_decoder(void) stream = create_stream(test_dds_image, sizeof(test_dds_image)); if (!stream) goto end; - todo_wine decoder = create_decoder(stream); + decoder = create_decoder(stream); if (!decoder) goto end; end: diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index 7686e80715f..e03cde4eb27 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -150,6 +150,7 @@ extern HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDE extern HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; extern HRESULT IcnsEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; extern HRESULT TgaDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; +extern HRESULT DdsDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; extern HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, UINT stride, UINT datasize, void *view, UINT offset, diff --git a/dlls/windowscodecs/windowscodecs_wincodec.idl b/dlls/windowscodecs/windowscodecs_wincodec.idl index 33c0d4a5801..24d48bcb5c2 100644 --- a/dlls/windowscodecs/windowscodecs_wincodec.idl +++ b/dlls/windowscodecs/windowscodecs_wincodec.idl @@ -118,6 +118,13 @@ coclass WICTiffEncoder { interface IWICBitmapEncoder; } ] coclass WICIcnsEncoder { interface IWICBitmapEncoder; } +[ + helpstring("WIC DDS Decoder"), + threading(both), + uuid(9053699f-a341-429d-9e90-ee437cf80c73) +] +coclass WICDdsDecoder { interface IWICBitmapDecoder; } + [ helpstring("WIC Default Format Converter"), threading(both),