[PATCH 1/8] windowscodecs: Add a unix library and start to use it for PNG.

Esme Povirk esme at codeweavers.com
Fri Oct 9 14:56:16 CDT 2020


Signed-off-by: Esme Povirk <esme at codeweavers.com>
---
 dlls/windowscodecs/Makefile.in         |   3 +
 dlls/windowscodecs/libpng.c            |  98 ++++++++++++++++++++++++
 dlls/windowscodecs/main.c              |   5 ++
 dlls/windowscodecs/pngformat.c         |  20 ++++-
 dlls/windowscodecs/unix_iface.c        | 102 +++++++++++++++++++++++++
 dlls/windowscodecs/unix_lib.c          |  66 ++++++++++++++++
 dlls/windowscodecs/wincodecs_common.h  |  23 ++++++
 dlls/windowscodecs/wincodecs_private.h |  35 +++++++++
 8 files changed, 349 insertions(+), 3 deletions(-)
 create mode 100644 dlls/windowscodecs/libpng.c
 create mode 100644 dlls/windowscodecs/unix_iface.c
 create mode 100644 dlls/windowscodecs/unix_lib.c
 create mode 100644 dlls/windowscodecs/wincodecs_common.h

diff --git a/dlls/windowscodecs/Makefile.in b/dlls/windowscodecs/Makefile.in
index fac90344fa3..fde28aea778 100644
--- a/dlls/windowscodecs/Makefile.in
+++ b/dlls/windowscodecs/Makefile.in
@@ -21,6 +21,7 @@ C_SRCS = \
 	imgfactory.c \
 	info.c \
 	jpegformat.c \
+	libpng.c \
 	main.c \
 	metadatahandler.c \
 	metadataquery.c \
@@ -34,6 +35,8 @@ C_SRCS = \
 	tgaformat.c \
 	tiffformat.c \
 	ungif.c \
+	unix_iface.c \
+	unix_lib.c \
 	uuid.c
 
 RC_SRCS = version.rc
diff --git a/dlls/windowscodecs/libpng.c b/dlls/windowscodecs/libpng.c
new file mode 100644
index 00000000000..336fbb389b8
--- /dev/null
+++ b/dlls/windowscodecs/libpng.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2020 Esme Povirk
+ *
+ * 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
+ */
+
+#if 0
+#pragma makedep unix
+#endif
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+
+#define NONAMELESSUNION
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winternl.h"
+#include "winbase.h"
+#include "objbase.h"
+
+#include "wincodecs_private.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
+
+#ifdef SONAME_LIBPNG
+
+struct png_decoder
+{
+    struct decoder decoder;
+};
+
+static inline struct png_decoder *impl_from_decoder(struct decoder* iface)
+{
+    return CONTAINING_RECORD(iface, struct png_decoder, decoder);
+}
+
+void CDECL png_decoder_destroy(struct decoder* iface)
+{
+    struct png_decoder *This = impl_from_decoder(iface);
+
+    RtlFreeHeap(GetProcessHeap(), 0, This);
+}
+
+static const struct decoder_funcs png_decoder_vtable = {
+    png_decoder_destroy
+};
+
+HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result)
+{
+    struct png_decoder *This;
+
+    TRACE("\n");
+
+    This = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*This));
+
+    if (!This)
+    {
+        return E_OUTOFMEMORY;
+    }
+
+    This->decoder.vtable = &png_decoder_vtable;
+    *result = &This->decoder;
+
+    info->container_format = GUID_ContainerFormatPng;
+    info->block_format = GUID_ContainerFormatPng;
+    info->clsid = CLSID_WICPngDecoder;
+
+    return S_OK;
+}
+
+#else
+
+HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result)
+{
+    ERR("Trying to load PNG picture, but PNG support is not compiled in.\n");
+    return E_FAIL;
+}
+
+#endif
+
diff --git a/dlls/windowscodecs/main.c b/dlls/windowscodecs/main.c
index 7e03112a63c..3849e24c2a1 100644
--- a/dlls/windowscodecs/main.c
+++ b/dlls/windowscodecs/main.c
@@ -32,8 +32,12 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
 
+#include "wincodecs_common.h"
+
 extern BOOL WINAPI WIC_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
 
+extern HMODULE windowscodecs_module;
+
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 {
 
@@ -41,6 +45,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
     {
         case DLL_PROCESS_ATTACH:
             DisableThreadLibraryCalls(hinstDLL);
+            windowscodecs_module = hinstDLL;
             break;
         case DLL_PROCESS_DETACH:
             ReleaseComponentInfos();
diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c
index 3cf47b4211f..3b326c1266f 100644
--- a/dlls/windowscodecs/pngformat.c
+++ b/dlls/windowscodecs/pngformat.c
@@ -444,6 +444,8 @@ typedef struct {
     IWICMetadataBlockReader IWICMetadataBlockReader_iface;
     LONG ref;
     IStream *stream;
+    struct decoder *png_decoder;
+    struct decoder_info decoder_info;
     png_structp png_ptr;
     png_infop info_ptr;
     png_infop end_info;
@@ -521,6 +523,8 @@ static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface)
             IStream_Release(This->stream);
         if (This->png_ptr)
             ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info);
+        if (This->png_decoder)
+            decoder_destroy(This->png_decoder);
         This->lock.DebugInfo->Spare[0] = 0;
         DeleteCriticalSection(&This->lock);
         HeapFree(GetProcessHeap(), 0, This->image_bits);
@@ -828,16 +832,18 @@ end:
 static HRESULT WINAPI PngDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
     GUID *pguidContainerFormat)
 {
-    memcpy(pguidContainerFormat, &GUID_ContainerFormatPng, sizeof(GUID));
+    PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
+    memcpy(pguidContainerFormat, &This->decoder_info.container_format, sizeof(GUID));
     return S_OK;
 }
 
 static HRESULT WINAPI PngDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
     IWICBitmapDecoderInfo **ppIDecoderInfo)
 {
+    PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
     TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
 
-    return get_decoder_info(&CLSID_WICPngDecoder, ppIDecoderInfo);
+    return get_decoder_info(&This->decoder_info.clsid, ppIDecoderInfo);
 }
 
 static HRESULT WINAPI PngDecoder_CopyPalette(IWICBitmapDecoder *iface,
@@ -1208,8 +1214,9 @@ static ULONG WINAPI PngDecoder_Block_Release(IWICMetadataBlockReader *iface)
 static HRESULT WINAPI PngDecoder_Block_GetContainerFormat(IWICMetadataBlockReader *iface,
     GUID *pguidContainerFormat)
 {
+    PngDecoder *This = impl_from_IWICMetadataBlockReader(iface);
     if (!pguidContainerFormat) return E_INVALIDARG;
-    memcpy(pguidContainerFormat, &GUID_ContainerFormatPng, sizeof(GUID));
+    memcpy(pguidContainerFormat, &This->decoder_info.block_format, sizeof(GUID));
     return S_OK;
 }
 
@@ -1312,6 +1319,13 @@ HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv)
     This = HeapAlloc(GetProcessHeap(), 0, sizeof(PngDecoder));
     if (!This) return E_OUTOFMEMORY;
 
+    ret = get_unix_decoder(&CLSID_WICPngDecoder, &This->decoder_info, &This->png_decoder);
+    if (FAILED(ret))
+    {
+        HeapFree(GetProcessHeap(), 0, This);
+        return ret;
+    }
+
     This->IWICBitmapDecoder_iface.lpVtbl = &PngDecoder_Vtbl;
     This->IWICBitmapFrameDecode_iface.lpVtbl = &PngDecoder_FrameVtbl;
     This->IWICMetadataBlockReader_iface.lpVtbl = &PngDecoder_BlockVtbl;
diff --git a/dlls/windowscodecs/unix_iface.c b/dlls/windowscodecs/unix_iface.c
new file mode 100644
index 00000000000..cae64a6774c
--- /dev/null
+++ b/dlls/windowscodecs/unix_iface.c
@@ -0,0 +1,102 @@
+/*
+ * unix_iface.c - This is the Win32 side of the Unix interface.
+ *
+ * Copyright 2020 Esme Povirk
+ *
+ * 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 <stdarg.h>
+
+#define NONAMELESSUNION
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "objbase.h"
+#include "winternl.h"
+
+#include "wincodecs_private.h"
+
+#include "wine/debug.h"
+
+static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
+
+static const struct unix_funcs *unix_funcs;
+
+static BOOL WINAPI load_unixlib( INIT_ONCE *once, void *param, void **context )
+{
+    __wine_init_unix_lib( windowscodecs_module, DLL_PROCESS_ATTACH, NULL, &unix_funcs );
+    return TRUE;
+}
+
+static void init_unixlib(void)
+{
+    InitOnceExecuteOnce( &init_once, load_unixlib, NULL, NULL );
+}
+
+struct decoder_wrapper
+{
+    struct decoder win32_decoder;
+    struct decoder *unix_decoder;
+};
+
+static inline struct decoder_wrapper *impl_from_decoder(struct decoder* iface)
+{
+    return CONTAINING_RECORD(iface, struct decoder_wrapper, win32_decoder);
+}
+
+void CDECL decoder_wrapper_destroy(struct decoder* iface)
+{
+    struct decoder_wrapper* This = impl_from_decoder(iface);
+    unix_funcs->decoder_destroy(This->unix_decoder);
+    HeapFree(GetProcessHeap(), 0, This);
+}
+
+static const struct decoder_funcs decoder_wrapper_vtable = {
+    decoder_wrapper_destroy
+};
+
+HRESULT get_unix_decoder(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result)
+{
+    HRESULT hr;
+    struct decoder_wrapper *wrapper;
+    struct decoder *unix_decoder;
+
+    init_unixlib();
+
+    hr = unix_funcs->decoder_create(decoder_clsid, info, &unix_decoder);
+
+    if (SUCCEEDED(hr))
+    {
+        wrapper = HeapAlloc(GetProcessHeap(), 0, sizeof(*wrapper));
+
+        if (!wrapper)
+        {
+            unix_funcs->decoder_destroy(unix_decoder);
+            return E_OUTOFMEMORY;
+        }
+
+        wrapper->win32_decoder.vtable = &decoder_wrapper_vtable;
+        wrapper->unix_decoder = unix_decoder;
+        *result = &wrapper->win32_decoder;
+    }
+
+    return hr;
+}
+
diff --git a/dlls/windowscodecs/unix_lib.c b/dlls/windowscodecs/unix_lib.c
new file mode 100644
index 00000000000..80321d5b745
--- /dev/null
+++ b/dlls/windowscodecs/unix_lib.c
@@ -0,0 +1,66 @@
+/*
+ * unix_lib.c - This is the Unix side of the Unix interface.
+ *
+ * Copyright 2020 Esme Povirk
+ *
+ * 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
+ */
+
+#if 0
+#pragma makedep unix
+#endif
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+
+#define NONAMELESSUNION
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winternl.h"
+#include "winbase.h"
+#include "objbase.h"
+
+#include "initguid.h"
+#include "wincodecs_private.h"
+
+#include "wine/debug.h"
+
+#include "wincodecs_common.h"
+
+HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result)
+{
+    if (IsEqualGUID(decoder_clsid, &CLSID_WICPngDecoder))
+        return png_decoder_create(info, result);
+
+    return E_NOTIMPL;
+}
+
+static const struct unix_funcs unix_funcs = {
+    decoder_create,
+    decoder_destroy
+};
+
+NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
+{
+    if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
+
+    *(const struct unix_funcs **)ptr_out = &unix_funcs;
+    return STATUS_SUCCESS;
+}
+
diff --git a/dlls/windowscodecs/wincodecs_common.h b/dlls/windowscodecs/wincodecs_common.h
new file mode 100644
index 00000000000..4592a7ee15b
--- /dev/null
+++ b/dlls/windowscodecs/wincodecs_common.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2020 Esme Povirk
+ *
+ * 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
+ */
+
+void CDECL decoder_destroy(struct decoder *decoder)
+{
+    decoder->vtable->destroy(decoder);
+}
+
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h
index f7665d11732..0085639b2e1 100644
--- a/dlls/windowscodecs/wincodecs_private.h
+++ b/dlls/windowscodecs/wincodecs_private.h
@@ -247,4 +247,39 @@ static inline const char *debug_wic_rect(const WICRect *rect)
     return wine_dbg_sprintf("(%u,%u)-(%u,%u)", rect->X, rect->Y, rect->Width, rect->Height);
 }
 
+HMODULE windowscodecs_module;
+
+/* unixlib iface */
+struct decoder_funcs;
+
+struct decoder_info
+{
+    GUID container_format;
+    GUID block_format;
+    CLSID clsid;
+};
+
+struct decoder
+{
+    const struct decoder_funcs *vtable;
+};
+
+struct decoder_funcs
+{
+    void (CDECL *destroy)(struct decoder* This);
+};
+
+HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result);
+void CDECL decoder_destroy(struct decoder *This);
+
+HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result);
+
+struct unix_funcs
+{
+    HRESULT (CDECL *decoder_create)(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result); 
+    void (CDECL *decoder_destroy)(struct decoder* This);
+};
+
+HRESULT get_unix_decoder(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result);
+
 #endif /* WINCODECS_PRIVATE_H */
-- 
2.17.1




More information about the wine-devel mailing list