[PATCH 1/5] gdiplus: Refactor to split up encode_image_wic().

Florian Will florian.will at gmail.com
Mon Feb 17 04:00:43 CST 2020


New functions initialize_encoder_wic(), encode_frame_wic() and
terminate_encoder_wic() are useful for implementing GdipSaveAdd() and
GdipSaveAddImage() later.

Signed-off-by: Florian Will <florian.will at gmail.com>
---
 dlls/gdiplus/gdiplus_private.h |  1 +
 dlls/gdiplus/image.c           | 79 ++++++++++++++++++++++++----------
 2 files changed, 58 insertions(+), 22 deletions(-)

diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 8c4fcceded..36e79e29eb 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -72,6 +72,7 @@ extern GpStatus gdip_transform_points(GpGraphics *graphics, GpCoordinateSpace ds
 
 extern GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) DECLSPEC_HIDDEN;
 extern GpStatus encode_image_png(GpImage *image, IStream* stream, GDIPCONST EncoderParameters* params) DECLSPEC_HIDDEN;
+extern GpStatus terminate_encoder_wic(IWICBitmapEncoder *encoder) DECLSPEC_HIDDEN;
 
 extern GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **result) DECLSPEC_HIDDEN;
 extern GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc) DECLSPEC_HIDDEN;
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index dcdc49c6d6..daf3169bd1 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -4435,13 +4435,41 @@ GpStatus WINGDIPAPI GdipSaveImageToFile(GpImage *image, GDIPCONST WCHAR* filenam
  *   These functions encode an image in different image file formats.
  */
 
-static GpStatus encode_image_wic(GpImage *image, IStream* stream,
-    REFGUID container, GDIPCONST EncoderParameters* params)
+static GpStatus initialize_encoder_wic(IStream *stream, REFGUID container,
+    IWICBitmapEncoder **encoder)
+{
+    IWICImagingFactory *factory;
+    HRESULT hr;
+
+    TRACE("%p,%s\n", stream, wine_dbgstr_guid(container));
+
+    hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory);
+    if (FAILED(hr)) return hresult_to_status(hr);
+    hr = IWICImagingFactory_CreateEncoder(factory, container, NULL, encoder);
+    IWICImagingFactory_Release(factory);
+    if (FAILED(hr)) return hresult_to_status(hr);
+
+    hr = IWICBitmapEncoder_Initialize(*encoder, stream, WICBitmapEncoderNoCache);
+    if (FAILED(hr))
+    {
+        IWICBitmapEncoder_Release(*encoder);
+        *encoder = NULL;
+        return hresult_to_status(hr);
+    }
+    return Ok;
+}
+
+GpStatus terminate_encoder_wic(IWICBitmapEncoder *encoder)
+{
+    HRESULT hr = IWICBitmapEncoder_Commit(encoder);
+    IWICBitmapEncoder_Release(encoder);
+    return hresult_to_status(hr);
+}
+
+static GpStatus encode_frame_wic(IWICBitmapEncoder *encoder, GpImage *image)
 {
     GpStatus stat;
     GpBitmap *bitmap;
-    IWICImagingFactory *factory;
-    IWICBitmapEncoder *encoder;
     IWICBitmapFrameEncode *frameencode;
     IPropertyBag2 *encoderoptions;
     HRESULT hr;
@@ -4466,20 +4494,7 @@ static GpStatus encode_image_wic(GpImage *image, IStream* stream,
     rc.Width = width;
     rc.Height = height;
 
-    hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory);
-    if (FAILED(hr))
-        return hresult_to_status(hr);
-    hr = IWICImagingFactory_CreateEncoder(factory, container, NULL, &encoder);
-    IWICImagingFactory_Release(factory);
-    if (FAILED(hr))
-        return hresult_to_status(hr);
-
-    hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache);
-
-    if (SUCCEEDED(hr))
-    {
-        hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, &encoderoptions);
-    }
+    hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, &encoderoptions);
 
     if (SUCCEEDED(hr)) /* created frame */
     {
@@ -4563,13 +4578,33 @@ static GpStatus encode_image_wic(GpImage *image, IStream* stream,
         IPropertyBag2_Release(encoderoptions);
     }
 
-    if (SUCCEEDED(hr))
-        hr = IWICBitmapEncoder_Commit(encoder);
-
-    IWICBitmapEncoder_Release(encoder);
     return hresult_to_status(hr);
 }
 
+static GpStatus encode_image_wic(GpImage *image, IStream *stream,
+    REFGUID container, GDIPCONST EncoderParameters *params)
+{
+    IWICBitmapEncoder *encoder = NULL;
+    GpStatus status;
+
+    if (image->type != ImageTypeBitmap)
+        return GenericError;
+
+    status = initialize_encoder_wic(stream, container, &encoder);
+
+    if (status == Ok)
+        status = encode_frame_wic(encoder, image);
+
+    if (encoder)
+    {
+        GpStatus terminate_status = terminate_encoder_wic(encoder);
+        if (status == Ok)
+            status = terminate_status;
+    }
+
+    return status;
+}
+
 static GpStatus encode_image_BMP(GpImage *image, IStream* stream,
     GDIPCONST EncoderParameters* params)
 {
-- 
2.20.1




More information about the wine-devel mailing list