Ziqing Hui : windowscodecs: Add stub implementation for DDS encoder.

Alexandre Julliard julliard at winehq.org
Tue Mar 16 16:39:03 CDT 2021


Module: wine
Branch: master
Commit: 8ee4c1e21c14bbfafc1aed9551047d30a1ff8e12
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=8ee4c1e21c14bbfafc1aed9551047d30a1ff8e12

Author: Ziqing Hui <zhui at codeweavers.com>
Date:   Mon Mar 15 10:59:17 2021 +0800

windowscodecs: Add stub implementation for DDS encoder.

Signed-off-by: Ziqing Hui <zhui at codeweavers.com>
Signed-off-by: Esme Povirk <esme at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/windowscodecs/clsfactory.c               |   1 +
 dlls/windowscodecs/ddsformat.c                | 196 ++++++++++++++++++++++++++
 dlls/windowscodecs/wincodecs_private.h        |   1 +
 dlls/windowscodecs/windowscodecs_wincodec.idl |   7 +
 4 files changed, 205 insertions(+)

diff --git a/dlls/windowscodecs/clsfactory.c b/dlls/windowscodecs/clsfactory.c
index b2914a7fd5b..f1be96dd11d 100644
--- a/dlls/windowscodecs/clsfactory.c
+++ b/dlls/windowscodecs/clsfactory.c
@@ -58,6 +58,7 @@ static const classinfo wic_classes[] = {
     {&CLSID_WICTiffEncoder, TiffEncoder_CreateInstance},
     {&CLSID_WICIcnsEncoder, IcnsEncoder_CreateInstance},
     {&CLSID_WICDdsDecoder, DdsDecoder_CreateInstance},
+    {&CLSID_WICDdsEncoder, DdsEncoder_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
index 0830519fbc0..873d4f1bb1f 100644
--- a/dlls/windowscodecs/ddsformat.c
+++ b/dlls/windowscodecs/ddsformat.c
@@ -159,6 +159,16 @@ typedef struct DdsFrameDecode {
     dds_frame_info info;
 } DdsFrameDecode;
 
+typedef struct DdsEncoder {
+    IWICBitmapEncoder IWICBitmapEncoder_iface;
+    LONG ref;
+    CRITICAL_SECTION lock;
+    IStream *stream;
+    UINT frame_count;
+    BOOL uncommitted_frame;
+    BOOL committed;
+} DdsEncoder;
+
 static struct dds_format {
     DDS_PIXELFORMAT pixel_format;
     const GUID *wic_format;
@@ -683,6 +693,11 @@ static inline DdsFrameDecode *impl_from_IWICDdsFrameDecode(IWICDdsFrameDecode *i
     return CONTAINING_RECORD(iface, DdsFrameDecode, IWICDdsFrameDecode_iface);
 }
 
+static inline DdsEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
+{
+    return CONTAINING_RECORD(iface, DdsEncoder, IWICBitmapEncoder_iface);
+}
+
 static HRESULT WINAPI DdsFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
                                                     void **ppv)
 {
@@ -1493,3 +1508,184 @@ HRESULT DdsDecoder_CreateInstance(REFIID iid, void** ppv)
 
     return ret;
 }
+
+static HRESULT WINAPI DdsEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid,
+                                                   void **ppv)
+{
+    DdsEncoder *This = impl_from_IWICBitmapEncoder(iface);
+    FIXME("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
+
+    if (!ppv) return E_INVALIDARG;
+
+    if (IsEqualIID(&IID_IUnknown, iid) ||
+        IsEqualIID(&IID_IWICBitmapEncoder, iid)) {
+        *ppv = &This->IWICBitmapEncoder_iface;
+    }
+    else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI DdsEncoder_AddRef(IWICBitmapEncoder *iface)
+{
+    DdsEncoder *This = impl_from_IWICBitmapEncoder(iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) refcount=%u\n", iface, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI DdsEncoder_Release(IWICBitmapEncoder *iface)
+{
+    DdsEncoder *This = impl_from_IWICBitmapEncoder(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 DdsEncoder_Initialize(IWICBitmapEncoder *iface,
+                                               IStream *pIStream, WICBitmapEncoderCacheOption cacheOption)
+{
+    FIXME("(%p,%p,%u): stub\n", iface, pIStream, cacheOption);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DdsEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format)
+{
+    TRACE("(%p,%p)\n", iface, format);
+
+    if (!format)
+        return E_INVALIDARG;
+
+    memcpy(format, &GUID_ContainerFormatDds, sizeof(*format));
+    return S_OK;
+}
+
+static HRESULT WINAPI DdsEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info)
+{
+    IWICComponentInfo *comp_info;
+    HRESULT hr;
+
+    TRACE("%p,%p\n", iface, info);
+
+    if (!info) return E_INVALIDARG;
+
+    hr = CreateComponentInfo(&CLSID_WICDdsEncoder, &comp_info);
+    if (hr == S_OK) {
+        hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info);
+        IWICComponentInfo_Release(comp_info);
+    }
+    return hr;
+}
+
+static HRESULT WINAPI DdsEncoder_SetColorContexts(IWICBitmapEncoder *iface,
+                                                     UINT cCount, IWICColorContext **ppIColorContext)
+{
+    FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DdsEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette)
+{
+    DdsEncoder *This = impl_from_IWICBitmapEncoder(iface);
+    HRESULT hr;
+
+    TRACE("(%p,%p)\n", iface, palette);
+
+    EnterCriticalSection(&This->lock);
+
+    hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED;
+
+    LeaveCriticalSection(&This->lock);
+
+    return hr;
+}
+
+static HRESULT WINAPI DdsEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail)
+{
+    TRACE("(%p,%p)\n", iface, pIThumbnail);
+    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+}
+
+static HRESULT WINAPI DdsEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview)
+{
+    TRACE("(%p,%p)\n", iface, pIPreview);
+    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+}
+
+static HRESULT WINAPI DdsEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
+                                                   IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions)
+{
+    FIXME("(%p,%p,%p): stub\n", iface, ppIFrameEncode, ppIEncoderOptions);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DdsEncoder_Commit(IWICBitmapEncoder *iface)
+{
+    FIXME("(%p): stub\n", iface);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DdsEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface,
+                                                           IWICMetadataQueryWriter **ppIMetadataQueryWriter)
+{
+    FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter);
+    return E_NOTIMPL;
+}
+
+static const IWICBitmapEncoderVtbl DdsEncoder_Vtbl = {
+    DdsEncoder_QueryInterface,
+    DdsEncoder_AddRef,
+    DdsEncoder_Release,
+    DdsEncoder_Initialize,
+    DdsEncoder_GetContainerFormat,
+    DdsEncoder_GetEncoderInfo,
+    DdsEncoder_SetColorContexts,
+    DdsEncoder_SetPalette,
+    DdsEncoder_SetThumbnail,
+    DdsEncoder_SetPreview,
+    DdsEncoder_CreateNewFrame,
+    DdsEncoder_Commit,
+    DdsEncoder_GetMetadataQueryWriter
+};
+
+HRESULT DdsEncoder_CreateInstance( REFIID iid, void **ppv)
+{
+    DdsEncoder *This;
+    HRESULT ret;
+
+    TRACE("(%s,%p)\n", debugstr_guid(iid), ppv);
+
+    *ppv = NULL;
+
+    This = HeapAlloc(GetProcessHeap(), 0, sizeof(DdsEncoder));
+    if (!This) return E_OUTOFMEMORY;
+
+    This->IWICBitmapEncoder_iface.lpVtbl = &DdsEncoder_Vtbl;
+    This->ref = 1;
+    This->stream = NULL;
+    This->frame_count = 0;
+    This->uncommitted_frame = FALSE;
+    This->committed = FALSE;
+    InitializeCriticalSection(&This->lock);
+    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DdsEncoder.lock");
+
+    ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv);
+    IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface);
+
+    return ret;
+}
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h
index 453bc58cca6..78a01a983c0 100644
--- a/dlls/windowscodecs/wincodecs_private.h
+++ b/dlls/windowscodecs/wincodecs_private.h
@@ -153,6 +153,7 @@ extern HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDE
 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 DdsEncoder_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 3519e6c6189..ed8154051ef 100644
--- a/dlls/windowscodecs/windowscodecs_wincodec.idl
+++ b/dlls/windowscodecs/windowscodecs_wincodec.idl
@@ -132,6 +132,13 @@ coclass WICIcnsEncoder { interface IWICBitmapEncoder; }
 ]
 coclass WICDdsDecoder { interface IWICBitmapDecoder; }
 
+[
+    helpstring("WIC DDS Encoder"),
+    threading(both),
+    uuid(a61dde94-66ce-4ac1-881b-71680588895e)
+]
+coclass WICDdsEncoder { interface IWICBitmapEncoder; }
+
 [
     helpstring("WIC Default Format Converter"),
     threading(both),




More information about the wine-cvs mailing list