From: Esme Povirk esme@codeweavers.com
--- dlls/gdiplus/gdiplus_private.h | 13 +++++++++ dlls/gdiplus/image.c | 50 +++++++++++++++++++++++++++++----- dlls/gdiplus/tests/image.c | 18 ++++++------ 3 files changed, 65 insertions(+), 16 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index a81220b130c..040d0ef4e8d 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -396,6 +396,19 @@ typedef enum EffectType {
typedef struct CGpEffect{ EffectType type; + union { + BYTE data[1]; + struct BlurParams blur; + struct TintParams tint; + struct RedEyeCorrectionParams redeye; + ColorMatrix matrix; + struct ColorLUTParams lut; + struct BrightnessContrastParams brightness; + struct HueSaturationLightnessParams hue; + struct ColorBalanceParams balance; + struct LevelsParams levels; + struct ColorCurveParams curve; + } params; } CGpEffect;
struct GpImage{ diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 527d319acab..24253ad298c 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -5549,6 +5549,7 @@ GpStatus WINGDIPAPI GdipCreateEffect(const GUID guid, CGpEffect **effect) { CGpEffect *ef = NULL; EffectType type; + UINT param_size;
TRACE("(%s, %p)\n", debugstr_guid(&guid), effect);
@@ -5605,7 +5606,9 @@ GpStatus WINGDIPAPI GdipCreateEffect(const GUID guid, CGpEffect **effect) return Win32Error; }
- ef = malloc(sizeof(CGpEffect)); + param_size = get_effect_parameter_size(type); + + ef = calloc(1, FIELD_OFFSET(CGpEffect, params.data[param_size])); ef->type = type; *effect = ef;
@@ -5652,12 +5655,30 @@ GpStatus WINGDIPAPI GdipGetEffectParameterSize(CGpEffect *effect, UINT *size) */ GpStatus WINGDIPAPI GdipGetEffectParameters(CGpEffect *effect, UINT *size, void *params) { - FIXME("(%p,%p,%p)\n", effect, size, params); + UINT params_size; + + TRACE("(%p,%p,%p)\n", effect, size, params);
if (!effect || !size || !params) return InvalidParameter;
- return NotImplemented; + if (effect->type == RedEyeCorrectionEffect) + { + static int calls; + if (!calls++) + FIXME("not implemented for RedEyeCorrectionEffect\n"); + return NotImplemented; + } + + params_size = get_effect_parameter_size(effect->type); + + if (*size < params_size) + return InvalidParameter; + + *size = params_size; + memcpy(params, effect->params.data, params_size); + + return Ok; }
/***************************************************************************** @@ -5666,14 +5687,29 @@ GpStatus WINGDIPAPI GdipGetEffectParameters(CGpEffect *effect, UINT *size, void GpStatus WINGDIPAPI GdipSetEffectParameters(CGpEffect *effect, const VOID *params, const UINT size) { - static int calls; + UINT params_size;
TRACE("(%p,%p,%u)\n", effect, params, size);
- if(!(calls++)) - FIXME("not implemented\n"); + if (!effect || !params) + return InvalidParameter;
- return NotImplemented; + if (effect->type == RedEyeCorrectionEffect) + { + static int calls; + if (!calls++) + FIXME("not implemented for RedEyeCorrectionEffect\n"); + return NotImplemented; + } + + params_size = get_effect_parameter_size(effect->type); + + if (size != params_size) + return InvalidParameter; + + memcpy(effect->params.data, params, size); + + return Ok; }
/***************************************************************************** diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index 1628e1486e6..c76f88aef94 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -5489,7 +5489,7 @@ static void test_createeffect(void)
param_size = sizeof(ColorMatrix)-1; stat = pGdipGetEffectParameters(effect, ¶m_size, &color_matrix); - todo_wine expect(InvalidParameter, stat); + expect(InvalidParameter, stat); expect(sizeof(ColorMatrix)-1, param_size);
for (i=0; i < 5; i++) @@ -5497,33 +5497,33 @@ static void test_createeffect(void) color_matrix.m[i][j] = i * j + 1;
stat = pGdipSetEffectParameters(effect, &color_matrix, sizeof(color_matrix)-1); - todo_wine expect(InvalidParameter, stat); + expect(InvalidParameter, stat);
stat = pGdipSetEffectParameters(effect, &color_matrix, sizeof(color_matrix)+1); - todo_wine expect(InvalidParameter, stat); + expect(InvalidParameter, stat);
stat = pGdipSetEffectParameters(effect, &color_matrix, sizeof(color_matrix)); - todo_wine expect(Ok, stat); + expect(Ok, stat);
param_size = sizeof(ColorMatrix)+1; memset(&color_matrix, 0, sizeof(color_matrix)); stat = pGdipGetEffectParameters(effect, ¶m_size, &color_matrix); - todo_wine expect(Ok, stat); - todo_wine expect(sizeof(ColorMatrix), param_size); + expect(Ok, stat); + expect(sizeof(ColorMatrix), param_size);
for (i=0; i < 5; i++) for (j=0; j < 5; j++) - todo_wine expectf((float)(i * j + 1), color_matrix.m[i][j]); + expectf((float)(i * j + 1), color_matrix.m[i][j]);
param_size = sizeof(ColorMatrix); memset(&color_matrix, 0, sizeof(color_matrix)); stat = pGdipGetEffectParameters(effect, ¶m_size, &color_matrix); - todo_wine expect(Ok, stat); + expect(Ok, stat); expect(sizeof(ColorMatrix), param_size);
for (i=0; i < 5; i++) for (j=0; j < 5; j++) - todo_wine expectf((float)(i * j + 1), color_matrix.m[i][j]); + expectf((float)(i * j + 1), color_matrix.m[i][j]);
stat = GdipDeleteEffect(effect); expect(Ok, stat);