Module: wine Branch: master Commit: a7fc06f62cf6bd691b86abba24d83292bd1399e8 URL: https://source.winehq.org/git/wine.git/?a=commit;h=a7fc06f62cf6bd691b86abba2...
Author: Florian Will florian.will@gmail.com Date: Wed Feb 19 08:47:07 2020 +0100
gdiplus: Implement GdipSaveAddImage() and GdipSaveAdd().
Signed-off-by: Florian Will florian.will@gmail.com Signed-off-by: Vincent Povirk vincent@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/gdiplus/image.c | 56 +++++++++++++++++++++++++++++++++++++++------- dlls/gdiplus/tests/image.c | 24 ++++++++++---------- 2 files changed, 60 insertions(+), 20 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 94c03ede19..f33e2328bf 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -4426,6 +4426,9 @@ GpStatus WINGDIPAPI GdipSaveImageToFile(GpImage *image, GDIPCONST WCHAR* filenam if (!image || !filename|| !clsidEncoder) return InvalidParameter;
+ /* this might release an old file stream held by the encoder so we can re-create it below */ + terminate_encoder_wic(image); + stat = GdipCreateStreamOnFile(filename, GENERIC_WRITE, &stream); if (stat != Ok) return GenericError; @@ -4598,6 +4601,29 @@ static GpStatus encode_frame_wic(IWICBitmapEncoder *encoder, GpImage *image) return hresult_to_status(hr); }
+static BOOL has_encoder_param_long(GDIPCONST EncoderParameters *params, GUID param_guid, ULONG val) +{ + int param_idx, value_idx; + + if (!params) + return FALSE; + + for (param_idx = 0; param_idx < params->Count; param_idx++) + { + EncoderParameter param = params->Parameter[param_idx]; + if (param.Type == EncoderParameterValueTypeLong && IsEqualCLSID(¶m.Guid, ¶m_guid)) + { + ULONG *value_array = (ULONG*) param.Value; + for (value_idx = 0; value_idx < param.NumberOfValues; value_idx++) + { + if (value_array[value_idx] == val) + return TRUE; + } + } + } + return FALSE; +} + static GpStatus encode_image_wic(GpImage *image, IStream *stream, REFGUID container, GDIPCONST EncoderParameters *params) { @@ -4611,10 +4637,13 @@ static GpStatus encode_image_wic(GpImage *image, IStream *stream, if (status == Ok) status = encode_frame_wic(image->encoder, image);
- /* always try to terminate, but if something already failed earlier, keep the old status. */ - terminate_status = terminate_encoder_wic(image); - if (status == Ok) - status = terminate_status; + if (!has_encoder_param_long(params, EncoderSaveFlag, EncoderValueMultiFrame)) + { + /* always try to terminate, but if something already failed earlier, keep the old status. */ + terminate_status = terminate_encoder_wic(image); + if (status == Ok) + status = terminate_status; + }
return status; } @@ -4687,8 +4716,7 @@ GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream* stream, */ GpStatus WINGDIPAPI GdipSaveAdd(GpImage *image, GDIPCONST EncoderParameters *params) { - FIXME("(%p,%p): stub\n", image, params); - return NotImplemented; + return GdipSaveAddImage(image, image, params); }
/***************************************************************************** @@ -4704,8 +4732,20 @@ GpStatus WINGDIPAPI GdipSaveAdd(GpImage *image, GDIPCONST EncoderParameters *par GpStatus WINGDIPAPI GdipSaveAddImage(GpImage *image, GpImage *additional_image, GDIPCONST EncoderParameters *params) { - FIXME("(%p,%p,%p): stub\n", image, additional_image, params); - return NotImplemented; + TRACE("%p, %p, %p\n", image, additional_image, params); + + if (!image || !additional_image || !params) + return InvalidParameter; + + if (!image->encoder) + return Win32Error; + + if (has_encoder_param_long(params, EncoderSaveFlag, EncoderValueFlush)) + return terminate_encoder_wic(image); + else if (has_encoder_param_long(params, EncoderSaveFlag, EncoderValueFrameDimensionPage)) + return encode_frame_wic(image->encoder, additional_image); + else + return InvalidParameter; }
/***************************************************************************** diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index 01d79f08c4..bbb9365edb 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -552,41 +552,41 @@ static void test_SavingMultiPageTiff(void)
/* invalid params: NULL */ stat = GdipSaveAdd(0, ¶ms); - todo_wine expect(InvalidParameter, stat); + expect(InvalidParameter, stat); stat = GdipSaveAdd((GpImage*)bm1, 0); - todo_wine expect(InvalidParameter, stat); + expect(InvalidParameter, stat);
stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, 0); - todo_wine expect(InvalidParameter, stat); + expect(InvalidParameter, stat); stat = GdipSaveAddImage((GpImage*)bm1, 0, ¶ms); - todo_wine expect(InvalidParameter, stat); + expect(InvalidParameter, stat); stat = GdipSaveAddImage(0, (GpImage*)bm2, ¶ms); - todo_wine expect(InvalidParameter, stat); + expect(InvalidParameter, stat);
/* win32 error: SaveAdd() can only be called after Save() with the MultiFrame param */ stat = GdipSaveAdd((GpImage*)bm1, ¶ms); - todo_wine expect(Win32Error, stat); + expect(Win32Error, stat); stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, ¶ms); - todo_wine expect(Win32Error, stat); + expect(Win32Error, stat);
stat = GdipSaveImageToFile((GpImage*)bm1, filename1, &tiff_clsid, 0); /* param not set! */ expect(Ok, stat); if (stat != Ok) goto cleanup;
stat = GdipSaveAdd((GpImage*)bm1, ¶ms); - todo_wine expect(Win32Error, stat); + expect(Win32Error, stat); stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, ¶ms); - todo_wine expect(Win32Error, stat); + expect(Win32Error, stat);
/* win32 error: can't flush before starting the encoding process */ paramValue = EncoderValueFlush; stat = GdipSaveAdd((GpImage*)bm1, ¶ms); - todo_wine expect(Win32Error, stat); + expect(Win32Error, stat);
/* win32 error: can't start encoding process through SaveAdd(), only Save() */ paramValue = EncoderValueMultiFrame; stat = GdipSaveAdd((GpImage*)bm1, ¶ms); - todo_wine expect(Win32Error, stat); + expect(Win32Error, stat);
/* start encoding process: add first frame (bm1) */ paramValue = EncoderValueMultiFrame; @@ -600,7 +600,7 @@ static void test_SavingMultiPageTiff(void) /* add second frame (bm2) */ paramValue = EncoderValueFrameDimensionPage; stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, ¶ms); - todo_wine expect(Ok, stat); + expect(Ok, stat); if (stat != Ok) goto cleanup;
/* finish encoding process */