[PATCH] gdiplus: Disable PNG encoding filters.

Florian Will florian.will at gmail.com
Mon Jan 24 03:49:39 CST 2022


This speeds up the encoding process, sometimes at the cost of increased
PNG file sizes. PNGs created using gdiplus on Windows 10 have filters
disabled, too, according to pngcheck.

The application "ZusiDisplay" encodes finished frames in PNG format and
sends them through a named pipe for "Zusi 3" to use as an in-game
texture, so performance matters for that use case to improve "embedded
display" FPS.

Signed-off-by: Florian Will <florian.will at gmail.com>
---
I noticed that a 1840x3052 mostly text-based website screenshot I used
for testing actually shrunk from 402kB to 349kB after disabling filters.
Maybe this is common for basic "draw some lines and shapes in gdiplus"
images? On win10, the same screenshot is 371kB because the zlib
compression level appears to be "fast" instead of "default", and win10
gdiplus stores an alpha channel, while wine stores the fully opaque
screenshot loaded from a BMP file as 24bit RGB without alpha (all
according to pngcheck).
---
 dlls/gdiplus/Makefile.in |  2 +-
 dlls/gdiplus/image.c     | 16 +++++++++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/dlls/gdiplus/Makefile.in b/dlls/gdiplus/Makefile.in
index ac12bd1c613..c87ec5ba827 100644
--- a/dlls/gdiplus/Makefile.in
+++ b/dlls/gdiplus/Makefile.in
@@ -1,6 +1,6 @@
 MODULE    = gdiplus.dll
 IMPORTLIB = gdiplus
-IMPORTS   = uuid shlwapi ole32 user32 gdi32
+IMPORTS   = uuid shlwapi ole32 oleaut32 user32 gdi32
 DELAYIMPORTS = windowscodecs
 
 C_SRCS = \
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index 518a9bf8689..56eb62392ec 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -4544,6 +4544,7 @@ static GpStatus encode_frame_wic(IWICBitmapEncoder *encoder, GpImage *image)
     GpBitmap *bitmap;
     IWICBitmapFrameEncode *frameencode;
     IPropertyBag2 *encoderoptions;
+    GUID container_format;
     HRESULT hr;
     UINT width, height;
     PixelFormat gdipformat=0;
@@ -4570,7 +4571,20 @@ static GpStatus encode_frame_wic(IWICBitmapEncoder *encoder, GpImage *image)
 
     if (SUCCEEDED(hr)) /* created frame */
     {
-        hr = IWICBitmapFrameEncode_Initialize(frameencode, encoderoptions);
+        hr = IWICBitmapEncoder_GetContainerFormat(encoder, &container_format);
+        if (SUCCEEDED(hr) && IsEqualGUID(&container_format, &GUID_ContainerFormatPng))
+        {
+            /* disable PNG filters for faster encoding */
+            PROPBAG2 filter_option = { .pstrName = (LPOLESTR) L"FilterOption" };
+            VARIANT filter_value;
+            VariantInit(&filter_value);
+            V_VT(&filter_value) = VT_UI1;
+            V_UI1(&filter_value) = WICPngFilterNone;
+            hr = IPropertyBag2_Write(encoderoptions, 1, &filter_option, &filter_value);
+        }
+
+        if (SUCCEEDED(hr))
+            hr = IWICBitmapFrameEncode_Initialize(frameencode, encoderoptions);
 
         if (SUCCEEDED(hr))
             hr = IWICBitmapFrameEncode_SetSize(frameencode, width, height);
-- 
2.32.0




More information about the wine-devel mailing list