From: Esme Povirk esme@codeweavers.com
--- dlls/gdiplus/gdiplus.spec | 2 +- dlls/gdiplus/image.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index 0f17bb02d4d..ff654558b72 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -613,7 +613,7 @@ 613 stdcall GdipCreateEffect(int128 ptr) 614 stdcall GdipDeleteEffect(ptr) 615 stdcall GdipGetEffectParameterSize(ptr ptr) -616 stub GdipGetEffectParameters +616 stdcall GdipGetEffectParameters(ptr ptr ptr) 617 stdcall GdipSetEffectParameters(ptr ptr long) 618 stdcall GdipInitializePalette(ptr long long long ptr) 619 stdcall GdipBitmapCreateApplyEffect(ptr long ptr ptr ptr ptr long ptr ptr) diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index cfc6f670260..0af022144e7 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -5652,6 +5652,19 @@ GpStatus WINGDIPAPI GdipGetEffectParameterSize(CGpEffect *effect, UINT *size) return status; }
+/***************************************************************************** + * GdipGetEffectParameters [GDIPLUS.@] + */ +GpStatus WINGDIPAPI GdipGetEffectParameters(CGpEffect *effect, UINT *size, void *params) +{ + FIXME("(%p,%p,%p)\n", effect, size, params); + + if (!effect || !size || !params) + return InvalidParameter; + + return NotImplemented; +} + /***************************************************************************** * GdipSetEffectParameters [GDIPLUS.@] */
From: Esme Povirk esme@codeweavers.com
--- dlls/gdiplus/tests/image.c | 63 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-)
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index 0cc038555ce..1628e1486e6 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -5418,12 +5418,14 @@ static void test_createeffect(void) GpStatus (WINAPI *pGdipCreateEffect)( const GUID guid, CGpEffect **effect); GpStatus (WINAPI *pGdipDeleteEffect)( CGpEffect *effect); GpStatus (WINAPI *pGdipGetEffectParameterSize)(CGpEffect *effect, UINT *size); - GpStatus (WINAPI *pGdipGetEffectParameters)(CGpEffect *effect, const VOID *params, const UINT size); + GpStatus (WINAPI *pGdipGetEffectParameters)(CGpEffect *effect, UINT *size, VOID *params); + GpStatus (WINAPI *pGdipSetEffectParameters)(CGpEffect *effect, const VOID *params, const UINT size); GpStatus stat; CGpEffect *effect = NULL; HMODULE mod = GetModuleHandleA("gdiplus.dll"); - int i; + int i, j; UINT param_size; + ColorMatrix color_matrix;
static const struct test_data { const GUID *effect; @@ -5452,7 +5454,8 @@ static void test_createeffect(void) pGdipDeleteEffect = (void*)GetProcAddress( mod, "GdipDeleteEffect"); pGdipGetEffectParameterSize = (void*)GetProcAddress( mod, "GdipGetEffectParameterSize"); pGdipGetEffectParameters = (void*)GetProcAddress( mod, "GdipGetEffectParameters"); - if (!pGdipCreateEffect || !pGdipDeleteEffect || !pGdipGetEffectParameterSize || !pGdipGetEffectParameters) + pGdipSetEffectParameters = (void*)GetProcAddress( mod, "GdipSetEffectParameters"); + if (!pGdipCreateEffect || !pGdipDeleteEffect || !pGdipGetEffectParameterSize || !pGdipGetEffectParameters || !pGdipSetEffectParameters) { /* GdipCreateEffect/GdipDeleteEffect/GdipGetEffectParameterSize/GdipGetEffectParameters were introduced in Windows Vista. */ win_skip("GDIPlus version 1.1 not available\n"); @@ -5466,11 +5469,65 @@ static void test_createeffect(void) expect(Win32Error, stat); ok( !effect, "expected null effect\n");
+ stat = pGdipCreateEffect(ColorMatrixEffectGuid, &effect); + expect(Ok, stat); + param_size = 0; stat = pGdipGetEffectParameterSize(NULL, ¶m_size); expect(InvalidParameter, stat); expect(0, param_size);
+ param_size = sizeof(ColorMatrix); + stat = pGdipGetEffectParameters(NULL, ¶m_size, &color_matrix); + expect(InvalidParameter, stat); + + stat = pGdipGetEffectParameters(effect, NULL, &color_matrix); + expect(InvalidParameter, stat); + + stat = pGdipGetEffectParameters(effect, ¶m_size, NULL); + expect(InvalidParameter, stat); + + param_size = sizeof(ColorMatrix)-1; + stat = pGdipGetEffectParameters(effect, ¶m_size, &color_matrix); + todo_wine expect(InvalidParameter, stat); + expect(sizeof(ColorMatrix)-1, param_size); + + for (i=0; i < 5; i++) + for (j=0; j < 5; j++) + color_matrix.m[i][j] = i * j + 1; + + stat = pGdipSetEffectParameters(effect, &color_matrix, sizeof(color_matrix)-1); + todo_wine expect(InvalidParameter, stat); + + stat = pGdipSetEffectParameters(effect, &color_matrix, sizeof(color_matrix)+1); + todo_wine expect(InvalidParameter, stat); + + stat = pGdipSetEffectParameters(effect, &color_matrix, sizeof(color_matrix)); + todo_wine 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); + + for (i=0; i < 5; i++) + for (j=0; j < 5; j++) + todo_wine 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(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]); + + stat = GdipDeleteEffect(effect); + expect(Ok, stat); + for (i = 0; i < ARRAY_SIZE(td); i++) { stat = pGdipCreateEffect(*(td[i].effect), &effect);
From: Esme Povirk esme@codeweavers.com
--- dlls/gdiplus/image.c | 71 ++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 38 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 0af022144e7..527d319acab 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -5511,6 +5511,37 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBi return retval; }
+static UINT get_effect_parameter_size(EffectType type) +{ + switch (type) + { + case BlurEffect: + return sizeof(struct BlurParams); + case SharpenEffect: + return sizeof(struct SharpenParams); + case TintEffect: + return sizeof(struct TintParams); + case RedEyeCorrectionEffect: + return sizeof(struct RedEyeCorrectionParams); + case ColorMatrixEffect: + return sizeof(ColorMatrix); + case ColorLUTEffect: + return sizeof(struct ColorLUTParams); + case BrightnessContrastEffect: + return sizeof(struct BrightnessContrastParams); + case HueSaturationLightnessEffect: + return sizeof(struct HueSaturationLightnessParams); + case ColorBalanceEffect: + return sizeof(struct ColorBalanceParams); + case LevelsEffect: + return sizeof(struct LevelsParams); + case ColorCurveEffect: + return sizeof(struct ColorCurveParams); + default: + return 0; + } +} + /***************************************************************************** * GdipCreateEffect [GDIPLUS.@] */ @@ -5608,45 +5639,9 @@ GpStatus WINGDIPAPI GdipGetEffectParameterSize(CGpEffect *effect, UINT *size) if (!effect || !size) return InvalidParameter;
- switch (effect->type) - { - case BlurEffect: - sz = sizeof(struct BlurParams); - break; - case SharpenEffect: - sz = sizeof(struct SharpenParams); - break; - case TintEffect: - sz = sizeof(struct TintParams); - break; - case RedEyeCorrectionEffect: - sz = sizeof(struct RedEyeCorrectionParams); - break; - case ColorMatrixEffect: - sz = sizeof(ColorMatrix); - break; - case ColorLUTEffect: - sz = sizeof(struct ColorLUTParams); - break; - case BrightnessContrastEffect: - sz = sizeof(struct BrightnessContrastParams); - break; - case HueSaturationLightnessEffect: - sz = sizeof(struct HueSaturationLightnessParams); - break; - case ColorBalanceEffect: - sz = sizeof(struct ColorBalanceParams); - break; - case LevelsEffect: - sz = sizeof(struct LevelsParams); - break; - case ColorCurveEffect: - sz = sizeof(struct ColorCurveParams); - break; - default: + sz = get_effect_parameter_size(effect->type); + if (!sz) status = InvalidParameter; - break; - }
*size = sz; return status;
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);