From: Vijay Kiran Kamuju infyquest@gmail.com
--- dlls/gdiplus/gdiplus_private.h | 13 +++++ dlls/gdiplus/image.c | 75 ++++++++++++++++++++++-- dlls/gdiplus/tests/image.c | 104 ++++++++++++++++++++++++++++----- include/gdipluseffects.h | 1 + 4 files changed, 175 insertions(+), 18 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 44d3e6d1000..6325ab40aa0 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -386,6 +386,19 @@ typedef enum EffectType { typedef struct CGpEffect{ INT datasize; void *data; + union params { + struct BlurParams *blurparams; + struct SharpenParams *sharpenparams; + struct TintParams *tintparams; + struct RedEyeCorrectionParams *redeyeparams; + ColorMatrix *clrmatrixparams; + struct ColorLUTParams *clrlutparams; + struct BrightnessContrastParams *brtcntrstparams; + struct HueSaturationLightnessParams *huesatliteparams; + struct ColorBalanceParams *clrbalanceparams; + struct LevelsParams *levelsparams; + struct ColorCurveParams *clrcurveparams; + } p; EffectType type; } CGpEffect;
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index b3a33cdc702..11498f24688 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -5637,6 +5637,7 @@ GpStatus WINGDIPAPI GdipCreateEffect(const GUID guid, CGpEffect **effect) ef = malloc(sizeof(CGpEffect)); ef->datasize = 0; ef->data = NULL; + ef->p.blurparams = NULL; ef->type = type; *effect = ef;
@@ -5680,6 +5681,8 @@ GpStatus WINGDIPAPI GdipGetEffectParameterSize(CGpEffect *effect, UINT *size) break; case RedEyeCorrectionEffect: sz = sizeof(struct RedEyeCorrectionParams); + if (effect->p.redeyeparams) + sz += effect->p.redeyeparams->numberOfAreas*sizeof(RECT); break; case ColorMatrixEffect: sz = sizeof(ColorMatrix); @@ -5706,25 +5709,87 @@ GpStatus WINGDIPAPI GdipGetEffectParameterSize(CGpEffect *effect, UINT *size) status = InvalidParameter; break; } - *size = sz; + return status; }
+void alloc_copy(const void *src, void *desc, UINT size) +{ + desc = malloc(size); + memcpy(desc, src, size); +} + /***************************************************************************** * GdipSetEffectParameters [GDIPLUS.@] */ GpStatus WINGDIPAPI GdipSetEffectParameters(CGpEffect *effect, const VOID *params, const UINT size) { - static int calls; + UINT paramsize = 0, num = 0;
TRACE("(%p,%p,%u)\n", effect, params, size);
- if(!(calls++)) - FIXME("not implemented\n"); + if (!effect || !params || !size) + return InvalidParameter;
- return NotImplemented; + if (GdipGetEffectParameterSize(effect, ¶msize) != Ok) + return InvalidParameter; + + if (effect->type == RedEyeCorrectionEffect) + { + if ((paramsize-size > 0) || (((size-paramsize)%sizeof(RECT)) != 0)) + return InvalidParameter; + } + else + { + if (paramsize != size) + return InvalidParameter; + } + + switch (effect->type) + { + case BlurEffect: + alloc_copy(params, effect->p.blurparams, size); + break; + case SharpenEffect: + alloc_copy(params, effect->p.sharpenparams, size); + break; + case TintEffect: + alloc_copy(params, effect->p.tintparams, size); + break; + case RedEyeCorrectionEffect: + num = (size-paramsize)/sizeof(RECT); + effect->p.redeyeparams = malloc(paramsize); + effect->p.redeyeparams->numberOfAreas = num; + alloc_copy(((struct RedEyeCorrectionParams *)params)->areas, effect->p.redeyeparams, num*sizeof(RECT)); + break; + case ColorMatrixEffect: + alloc_copy(params, effect->p.clrmatrixparams, size); + break; + case ColorLUTEffect: + alloc_copy(params, effect->p.clrlutparams, size); + break; + case BrightnessContrastEffect: + alloc_copy(params, effect->p.brtcntrstparams, size); + break; + case HueSaturationLightnessEffect: + alloc_copy(params, effect->p.huesatliteparams, size); + break; + case ColorBalanceEffect: + alloc_copy(params, effect->p.clrbalanceparams, size); + break; + case LevelsEffect: + alloc_copy(params, effect->p.levelsparams, size); + break; + case ColorCurveEffect: + alloc_copy(params, effect->p.clrcurveparams, size); + break; + default: + return InvalidParameter; + } + + return Ok; }
/***************************************************************************** diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index ddeb8aeed80..5883009e233 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -5408,37 +5408,96 @@ 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 *pGdipSetEffectParameters)( CGpEffect *effect, const VOID *params, const UINT size); GpStatus stat; CGpEffect *effect; UINT size; + void *params = NULL; HMODULE mod = GetModuleHandleA("gdiplus.dll"); int i;
- static const struct test_data { + RECT rects[2] = { { 0, 0, 75, 75 }, { -32, -32, 32, 32 } }; + struct BlurParams blur = { 2.0, TRUE }; + struct SharpenParams sharpen = { 5.0, 2 }; + ColorMatrix matrix = + { + { + { 1.0, 1.0, 1.0, 1.0, 1.0 }, + { 2.0, 2.0, 2.0, 2.0, 2.0 }, + { 3.0, 3.0, 3.0, 3.0, 3.0 }, + { 4.0, 4.0, 4.0, 4.0, 4.0 }, + { 5.0, 5.0, 5.0, 5.0, 5.0 } + } + }; + struct ColorLUTParams lut = + { + { 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7, + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7, + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7, + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7 }, + { 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11, + 12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15, + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11, + 12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15 }, + { 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3 }, + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } + }; + struct BrightnessContrastParams bc = { 75, 50 }; + struct HueSaturationLightnessParams hsl = { 50, 50, 50 }; + struct LevelsParams lvl = { 50, 50, 5 }; + struct TintParams tint = { 20, 5 }; + struct ColorBalanceParams cbal = { 50, 50, 50 }; + struct ColorCurveParams ccurve = { AdjustExposure, CurveChannelAll, 5 }; + struct RedEyeCorrectionParams redi = { 2, rects }; + const struct test_data { const GUID *guid; UINT size; + void *params; } td[] = { - { &BlurEffectGuid, 8 }, - { &SharpenEffectGuid, 8 }, - { &ColorMatrixEffectGuid, 100 }, - { &ColorLUTEffectGuid, 1024 }, - { &BrightnessContrastEffectGuid, 8 }, - { &HueSaturationLightnessEffectGuid, 12 }, - { &LevelsEffectGuid, 12 }, - { &TintEffectGuid, 8 }, - { &ColorBalanceEffectGuid, 12 }, + { &BlurEffectGuid, 8, &blur }, + { &SharpenEffectGuid, 8, &sharpen }, + { &ColorMatrixEffectGuid, 100, &matrix }, + { &ColorLUTEffectGuid, 1024, &lut }, + { &BrightnessContrastEffectGuid, 8, &bc }, + { &HueSaturationLightnessEffectGuid, 12, &hsl }, + { &LevelsEffectGuid, 12, &lvl }, + { &TintEffectGuid, 8, &tint }, + { &ColorBalanceEffectGuid, 12, &cbal }, #ifdef _WIN64 - { &RedEyeCorrectionEffectGuid, 16 }, + { &RedEyeCorrectionEffectGuid, 16, &redi }, #else - { &RedEyeCorrectionEffectGuid, 8 }, + { &RedEyeCorrectionEffectGuid, 8, &redi }, #endif - { &ColorCurveEffectGuid, 12 } + { &ColorCurveEffectGuid, 12, &ccurve } };
pGdipCreateEffect = (void*)GetProcAddress( mod, "GdipCreateEffect"); pGdipDeleteEffect = (void*)GetProcAddress( mod, "GdipDeleteEffect"); pGdipGetEffectParameterSize = (void*)GetProcAddress( mod, "GdipGetEffectParameterSize"); + pGdipSetEffectParameters = (void*)GetProcAddress( mod, "GdipSetEffectParameters"); if(!pGdipCreateEffect || !pGdipDeleteEffect) { /* GdipCreateEffect/GdipDeleteEffect was introduced in Windows Vista. */ @@ -5452,14 +5511,27 @@ static void test_createeffect(void) stat = pGdipGetEffectParameterSize(NULL, NULL); expect(InvalidParameter, stat);
+ stat = pGdipSetEffectParameters(NULL, NULL, 0); + expect(InvalidParameter, stat); + stat = pGdipGetEffectParameterSize(effect, NULL); expect(InvalidParameter, stat);
+ stat = pGdipSetEffectParameters(effect, params, 0); + expect(InvalidParameter, stat); + effect = (CGpEffect *)0xdeadbeef; stat = pGdipCreateEffect(noneffect, &effect); expect(Win32Error, stat); ok(effect == NULL, "Expected effect to be NULL\n");
+ stat = pGdipSetEffectParameters(effect, (void *)0xdeadbeef, 0); + expect(InvalidParameter, stat); + stat = pGdipSetEffectParameters(effect, (void *)0xdeadbeef, 8); + expect(InvalidParameter, stat); + stat = pGdipSetEffectParameters(effect, (void *)0xdeadbeef, 5); + expect(InvalidParameter, stat); + for(i=0; i < ARRAY_SIZE(td); i++) { stat = pGdipCreateEffect(*td[i].guid, &effect); @@ -5472,6 +5544,12 @@ static void test_createeffect(void) expect(Ok, stat); expect(td[i].size, size);
+ stat = pGdipSetEffectParameters(effect, td[i].params, td[i].size); + expect(Ok, stat); + size = 0; + stat = pGdipGetEffectParameterSize(effect, &size); + expect(td[i].size, size); + stat = pGdipDeleteEffect(effect); expect(Ok, stat); } diff --git a/include/gdipluseffects.h b/include/gdipluseffects.h index a58d25cb0e3..2b94479f7f5 100644 --- a/include/gdipluseffects.h +++ b/include/gdipluseffects.h @@ -112,6 +112,7 @@ extern "C" { GpStatus WINGDIPAPI GdipCreateEffect(const GUID guid, CGpEffect **effect); GpStatus WINGDIPAPI GdipDeleteEffect(CGpEffect *effect); GpStatus WINGDIPAPI GdipGetEffectParameterSize(CGpEffect *effect, UINT *size); +GpStatus WINGDIPAPI GdipSetEffectParameters(CGpEffect *effect, const VOID *params, const UINT size);
#ifdef __cplusplus }