Commit a7fc06f6 authored by Florian Will's avatar Florian Will Committed by Alexandre Julliard

gdiplus: Implement GdipSaveAddImage() and GdipSaveAdd().

parent 21b62920
...@@ -4426,6 +4426,9 @@ GpStatus WINGDIPAPI GdipSaveImageToFile(GpImage *image, GDIPCONST WCHAR* filenam ...@@ -4426,6 +4426,9 @@ GpStatus WINGDIPAPI GdipSaveImageToFile(GpImage *image, GDIPCONST WCHAR* filenam
if (!image || !filename|| !clsidEncoder) if (!image || !filename|| !clsidEncoder)
return InvalidParameter; 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); stat = GdipCreateStreamOnFile(filename, GENERIC_WRITE, &stream);
if (stat != Ok) if (stat != Ok)
return GenericError; return GenericError;
...@@ -4598,6 +4601,29 @@ static GpStatus encode_frame_wic(IWICBitmapEncoder *encoder, GpImage *image) ...@@ -4598,6 +4601,29 @@ static GpStatus encode_frame_wic(IWICBitmapEncoder *encoder, GpImage *image)
return hresult_to_status(hr); 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(&param.Guid, &param_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, static GpStatus encode_image_wic(GpImage *image, IStream *stream,
REFGUID container, GDIPCONST EncoderParameters *params) REFGUID container, GDIPCONST EncoderParameters *params)
{ {
...@@ -4611,10 +4637,13 @@ static GpStatus encode_image_wic(GpImage *image, IStream *stream, ...@@ -4611,10 +4637,13 @@ static GpStatus encode_image_wic(GpImage *image, IStream *stream,
if (status == Ok) if (status == Ok)
status = encode_frame_wic(image->encoder, image); status = encode_frame_wic(image->encoder, image);
if (!has_encoder_param_long(params, EncoderSaveFlag, EncoderValueMultiFrame))
{
/* always try to terminate, but if something already failed earlier, keep the old status. */ /* always try to terminate, but if something already failed earlier, keep the old status. */
terminate_status = terminate_encoder_wic(image); terminate_status = terminate_encoder_wic(image);
if (status == Ok) if (status == Ok)
status = terminate_status; status = terminate_status;
}
return status; return status;
} }
...@@ -4687,8 +4716,7 @@ GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream* stream, ...@@ -4687,8 +4716,7 @@ GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream* stream,
*/ */
GpStatus WINGDIPAPI GdipSaveAdd(GpImage *image, GDIPCONST EncoderParameters *params) GpStatus WINGDIPAPI GdipSaveAdd(GpImage *image, GDIPCONST EncoderParameters *params)
{ {
FIXME("(%p,%p): stub\n", image, params); return GdipSaveAddImage(image, image, params);
return NotImplemented;
} }
/***************************************************************************** /*****************************************************************************
...@@ -4704,8 +4732,20 @@ GpStatus WINGDIPAPI GdipSaveAdd(GpImage *image, GDIPCONST EncoderParameters *par ...@@ -4704,8 +4732,20 @@ GpStatus WINGDIPAPI GdipSaveAdd(GpImage *image, GDIPCONST EncoderParameters *par
GpStatus WINGDIPAPI GdipSaveAddImage(GpImage *image, GpImage *additional_image, GpStatus WINGDIPAPI GdipSaveAddImage(GpImage *image, GpImage *additional_image,
GDIPCONST EncoderParameters *params) GDIPCONST EncoderParameters *params)
{ {
FIXME("(%p,%p,%p): stub\n", image, additional_image, params); TRACE("%p, %p, %p\n", image, additional_image, params);
return NotImplemented;
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;
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -552,41 +552,41 @@ static void test_SavingMultiPageTiff(void) ...@@ -552,41 +552,41 @@ static void test_SavingMultiPageTiff(void)
/* invalid params: NULL */ /* invalid params: NULL */
stat = GdipSaveAdd(0, &params); stat = GdipSaveAdd(0, &params);
todo_wine expect(InvalidParameter, stat); expect(InvalidParameter, stat);
stat = GdipSaveAdd((GpImage*)bm1, 0); stat = GdipSaveAdd((GpImage*)bm1, 0);
todo_wine expect(InvalidParameter, stat); expect(InvalidParameter, stat);
stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, 0); stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, 0);
todo_wine expect(InvalidParameter, stat); expect(InvalidParameter, stat);
stat = GdipSaveAddImage((GpImage*)bm1, 0, &params); stat = GdipSaveAddImage((GpImage*)bm1, 0, &params);
todo_wine expect(InvalidParameter, stat); expect(InvalidParameter, stat);
stat = GdipSaveAddImage(0, (GpImage*)bm2, &params); stat = GdipSaveAddImage(0, (GpImage*)bm2, &params);
todo_wine expect(InvalidParameter, stat); expect(InvalidParameter, stat);
/* win32 error: SaveAdd() can only be called after Save() with the MultiFrame param */ /* win32 error: SaveAdd() can only be called after Save() with the MultiFrame param */
stat = GdipSaveAdd((GpImage*)bm1, &params); stat = GdipSaveAdd((GpImage*)bm1, &params);
todo_wine expect(Win32Error, stat); expect(Win32Error, stat);
stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, &params); stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, &params);
todo_wine expect(Win32Error, stat); expect(Win32Error, stat);
stat = GdipSaveImageToFile((GpImage*)bm1, filename1, &tiff_clsid, 0); /* param not set! */ stat = GdipSaveImageToFile((GpImage*)bm1, filename1, &tiff_clsid, 0); /* param not set! */
expect(Ok, stat); expect(Ok, stat);
if (stat != Ok) goto cleanup; if (stat != Ok) goto cleanup;
stat = GdipSaveAdd((GpImage*)bm1, &params); stat = GdipSaveAdd((GpImage*)bm1, &params);
todo_wine expect(Win32Error, stat); expect(Win32Error, stat);
stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, &params); stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, &params);
todo_wine expect(Win32Error, stat); expect(Win32Error, stat);
/* win32 error: can't flush before starting the encoding process */ /* win32 error: can't flush before starting the encoding process */
paramValue = EncoderValueFlush; paramValue = EncoderValueFlush;
stat = GdipSaveAdd((GpImage*)bm1, &params); stat = GdipSaveAdd((GpImage*)bm1, &params);
todo_wine expect(Win32Error, stat); expect(Win32Error, stat);
/* win32 error: can't start encoding process through SaveAdd(), only Save() */ /* win32 error: can't start encoding process through SaveAdd(), only Save() */
paramValue = EncoderValueMultiFrame; paramValue = EncoderValueMultiFrame;
stat = GdipSaveAdd((GpImage*)bm1, &params); stat = GdipSaveAdd((GpImage*)bm1, &params);
todo_wine expect(Win32Error, stat); expect(Win32Error, stat);
/* start encoding process: add first frame (bm1) */ /* start encoding process: add first frame (bm1) */
paramValue = EncoderValueMultiFrame; paramValue = EncoderValueMultiFrame;
...@@ -600,7 +600,7 @@ static void test_SavingMultiPageTiff(void) ...@@ -600,7 +600,7 @@ static void test_SavingMultiPageTiff(void)
/* add second frame (bm2) */ /* add second frame (bm2) */
paramValue = EncoderValueFrameDimensionPage; paramValue = EncoderValueFrameDimensionPage;
stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, &params); stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, &params);
todo_wine expect(Ok, stat); expect(Ok, stat);
if (stat != Ok) goto cleanup; if (stat != Ok) goto cleanup;
/* finish encoding process */ /* finish encoding process */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment