[PATCH 2/3] windowscodecs: Add support for IMILBitmapScaler interface.

Dmitry Timoshkov dmitry at baikal.ru
Tue May 14 22:36:46 CDT 2019


This patch makes the GOG downloader work.

Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/windowscodecs/scaler.c            | 148 +++++++++++++++++++++++++
 dlls/windowscodecs/wincodecs_private.h |  19 ++++
 2 files changed, 167 insertions(+)

diff --git a/dlls/windowscodecs/scaler.c b/dlls/windowscodecs/scaler.c
index eedc1bbac4..c6c758d320 100644
--- a/dlls/windowscodecs/scaler.c
+++ b/dlls/windowscodecs/scaler.c
@@ -1,5 +1,6 @@
 /*
  * Copyright 2010 Vincent Povirk for CodeWeavers
+ * Copyright 2016 Dmitry Timoshkov
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -35,6 +36,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
 typedef struct BitmapScaler {
     IWICBitmapScaler IWICBitmapScaler_iface;
     LONG ref;
+    IMILBitmapScaler IMILBitmapScaler_iface;
     IWICBitmapSource *source;
     UINT width, height;
     UINT src_width, src_height;
@@ -50,6 +52,11 @@ static inline BitmapScaler *impl_from_IWICBitmapScaler(IWICBitmapScaler *iface)
     return CONTAINING_RECORD(iface, BitmapScaler, IWICBitmapScaler_iface);
 }
 
+static inline BitmapScaler *impl_from_IMILBitmapScaler(IMILBitmapScaler *iface)
+{
+    return CONTAINING_RECORD(iface, BitmapScaler, IMILBitmapScaler_iface);
+}
+
 static HRESULT WINAPI BitmapScaler_QueryInterface(IWICBitmapScaler *iface, REFIID iid,
     void **ppv)
 {
@@ -64,8 +71,13 @@ static HRESULT WINAPI BitmapScaler_QueryInterface(IWICBitmapScaler *iface, REFII
     {
         *ppv = &This->IWICBitmapScaler_iface;
     }
+    else if (IsEqualIID(&IID_IMILBitmapScaler, iid))
+    {
+        *ppv = &This->IMILBitmapScaler_iface;
+    }
     else
     {
+        FIXME("unknown interface %s\n", debugstr_guid(iid));
         *ppv = NULL;
         return E_NOINTERFACE;
     }
@@ -380,6 +392,141 @@ static const IWICBitmapScalerVtbl BitmapScaler_Vtbl = {
     BitmapScaler_Initialize
 };
 
+static HRESULT WINAPI IMILBitmapScaler_QueryInterface(IMILBitmapScaler *iface, REFIID iid,
+    void **ppv)
+{
+    BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
+    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
+    return IWICBitmapScaler_QueryInterface(&This->IWICBitmapScaler_iface, iid, ppv);
+}
+
+static ULONG WINAPI IMILBitmapScaler_AddRef(IMILBitmapScaler *iface)
+{
+    BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
+    return IWICBitmapScaler_AddRef(&This->IWICBitmapScaler_iface);
+}
+
+static ULONG WINAPI IMILBitmapScaler_Release(IMILBitmapScaler *iface)
+{
+    BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
+    return IWICBitmapScaler_Release(&This->IWICBitmapScaler_iface);
+}
+
+static HRESULT WINAPI IMILBitmapScaler_GetSize(IMILBitmapScaler *iface,
+    UINT *width, UINT *height)
+{
+    BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
+
+    TRACE("(%p,%p,%p)\n", iface, width, height);
+
+    if (!This->source)
+        return WINCODEC_ERR_NOTINITIALIZED;
+
+    return IWICBitmapScaler_GetSize(&This->IWICBitmapScaler_iface, width, height);
+}
+
+static HRESULT WINAPI IMILBitmapScaler_GetPixelFormat(IMILBitmapScaler *iface,
+    int *format)
+{
+    BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
+    IMILBitmapSource *source;
+    HRESULT hr;
+
+    TRACE("(%p,%p)\n", iface, format);
+
+    if (!format) return E_INVALIDARG;
+
+    if (!This->source)
+        return WINCODEC_ERR_NOTINITIALIZED;
+
+    hr = IWICBitmapSource_QueryInterface(This->source, &IID_IMILBitmapSource, (void **)&source);
+    if (hr == S_OK)
+    {
+        hr = source->lpVtbl->GetPixelFormat(source, format);
+        source->lpVtbl->Release(source);
+    }
+    return hr;
+}
+
+static HRESULT WINAPI IMILBitmapScaler_GetResolution(IMILBitmapScaler *iface,
+    double *dpix, double *dpiy)
+{
+    BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
+
+    TRACE("(%p,%p,%p)\n", iface, dpix, dpiy);
+
+    if (!This->source)
+        return WINCODEC_ERR_NOTINITIALIZED;
+
+    return IWICBitmapScaler_GetResolution(&This->IWICBitmapScaler_iface, dpix, dpiy);
+}
+
+static HRESULT WINAPI IMILBitmapScaler_CopyPalette(IMILBitmapScaler *iface,
+    IWICPalette *palette)
+{
+    BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
+
+    TRACE("(%p,%p)\n", iface, palette);
+
+    if (!This->source)
+        return WINCODEC_ERR_NOTINITIALIZED;
+
+    return IWICBitmapScaler_CopyPalette(&This->IWICBitmapScaler_iface, palette);
+}
+
+static HRESULT WINAPI IMILBitmapScaler_CopyPixels(IMILBitmapScaler *iface,
+    const WICRect *rc, UINT stride, UINT size, BYTE *buffer)
+{
+    BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
+
+    TRACE("(%p,%p,%u,%u,%p)\n", iface, rc, stride, size, buffer);
+
+    if (!This->source)
+        return WINCODEC_ERR_NOTINITIALIZED;
+
+    return IWICBitmapScaler_CopyPixels(&This->IWICBitmapScaler_iface, rc, stride, size, buffer);
+}
+
+static HRESULT WINAPI IMILBitmapScaler_unknown1(IMILBitmapScaler *iface, void **ppv)
+{
+    TRACE("(%p,%p)\n", iface, ppv);
+    return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI IMILBitmapScaler_Initialize(IMILBitmapScaler *iface,
+    IMILBitmapSource *mil_source, UINT width, UINT height,
+    WICBitmapInterpolationMode mode)
+{
+    BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
+    IWICBitmapSource *wic_source;
+    HRESULT hr;
+
+    TRACE("(%p,%p,%u,%u,%u)\n", iface, mil_source, width, height, mode);
+
+    if (!mil_source) return E_INVALIDARG;
+
+    hr = mil_source->lpVtbl->QueryInterface(mil_source, &IID_IWICBitmapSource, (void **)&wic_source);
+    if (hr == S_OK)
+    {
+        hr = IWICBitmapScaler_Initialize(&This->IWICBitmapScaler_iface, wic_source, width, height, mode);
+        IWICBitmapSource_Release(wic_source);
+    }
+    return hr;
+}
+
+static const IMILBitmapScalerVtbl IMILBitmapScaler_Vtbl = {
+    IMILBitmapScaler_QueryInterface,
+    IMILBitmapScaler_AddRef,
+    IMILBitmapScaler_Release,
+    IMILBitmapScaler_GetSize,
+    IMILBitmapScaler_GetPixelFormat,
+    IMILBitmapScaler_GetResolution,
+    IMILBitmapScaler_CopyPalette,
+    IMILBitmapScaler_CopyPixels,
+    IMILBitmapScaler_unknown1,
+    IMILBitmapScaler_Initialize
+};
+
 HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler)
 {
     BitmapScaler *This;
@@ -388,6 +535,7 @@ HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler)
     if (!This) return E_OUTOFMEMORY;
 
     This->IWICBitmapScaler_iface.lpVtbl = &BitmapScaler_Vtbl;
+    This->IMILBitmapScaler_iface.lpVtbl = &IMILBitmapScaler_Vtbl;
     This->ref = 1;
     This->source = NULL;
     This->width = 0;
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h
index 439c81d362..d5e586b8cd 100644
--- a/dlls/windowscodecs/wincodecs_private.h
+++ b/dlls/windowscodecs/wincodecs_private.h
@@ -79,6 +79,25 @@ DECLARE_INTERFACE_(IMILBitmap,IMILBitmapSource)
 };
 #undef INTERFACE
 
+#define INTERFACE IMILBitmapScaler
+DECLARE_INTERFACE_(IMILBitmapScaler,IMILBitmapSource)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID,void **) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IWICBitmapSource methods ***/
+    STDMETHOD_(HRESULT,GetSize)(THIS_ UINT *,UINT *) PURE;
+    STDMETHOD_(HRESULT,GetPixelFormat)(THIS_ int *) PURE;
+    STDMETHOD_(HRESULT,GetResolution)(THIS_ double *,double *) PURE;
+    STDMETHOD_(HRESULT,CopyPalette)(THIS_ IWICPalette *) PURE;
+    STDMETHOD_(HRESULT,CopyPixels)(THIS_ const WICRect *,UINT,UINT,BYTE *) PURE;
+    /*** IMILBitmapScaler methods ***/
+    STDMETHOD_(HRESULT,unknown1)(THIS_ void **) PURE;
+    STDMETHOD_(HRESULT,Initialize)(THIS_ IMILBitmapSource *,UINT,UINT,WICBitmapInterpolationMode) PURE;
+};
+#undef INTERFACE
+
 #ifdef __i386__  /* thiscall functions are i386-specific */
 
 #define THISCALL(func) __thiscall_ ## func
-- 
2.20.1




More information about the wine-devel mailing list