Implement effect related functions in Gdiplus. This currently a WIP.
-- v7: gdiplus: Add GdipGetEffectParameters implementation. gdiplus: Add GdipSetEffectsParameters implementation. gdiplus: Add GdipGetEffectParameterSize implementation. gdiplus: Add GdipCreateEffect implementation.
From: Vijay Kiran Kamuju infyquest@gmail.com
--- include/gdipluscolormatrix.h | 1 + include/gdipluseffects.h | 74 ++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+)
diff --git a/include/gdipluscolormatrix.h b/include/gdipluscolormatrix.h index 44016ff3451..391095ed8fb 100644 --- a/include/gdipluscolormatrix.h +++ b/include/gdipluscolormatrix.h @@ -62,6 +62,7 @@ enum HistogramFormat
#ifndef __cplusplus
+typedef BYTE ColorChannelLUT[256]; typedef enum ColorAdjustType ColorAdjustType; typedef enum ColorMatrixFlags ColorMatrixFlags; typedef enum HistogramFormat HistogramFormat; diff --git a/include/gdipluseffects.h b/include/gdipluseffects.h index d2d6a0500da..4100647f7a1 100644 --- a/include/gdipluseffects.h +++ b/include/gdipluseffects.h @@ -31,6 +31,80 @@ DEFINE_GUID(ColorBalanceEffectGuid, 0x537e597d, 0x251e, 0x48da, 0x96, DEFINE_GUID(RedEyeCorrectionEffectGuid, 0x74d29d05, 0x69a4, 0x4266, 0x95, 0x49, 0x3c, 0xc5, 0x28, 0x36, 0xb6, 0x32); DEFINE_GUID(ColorCurveEffectGuid, 0xdd6a0022, 0x58e4, 0x4a67, 0x9d, 0x9b, 0xd4, 0x8e, 0xb8, 0x81, 0xa5, 0x3d);
+struct BlurParams { + float radius; + BOOL expandEdge; +}; + +struct SharpenParams { + float radius; + float amount; +}; + +struct TintParams { + INT hue; + INT amount; +}; + +struct RedEyeCorrectionParams { + UINT numberOfAreas; + RECT *areas; +}; + +struct ColorLUTParams { + ColorChannelLUT lutB; + ColorChannelLUT lutG; + ColorChannelLUT lutR; + ColorChannelLUT lutA; +}; + +struct BrightnessContrastParams { + INT brightnessLevel; + INT contrastLevel; +}; + +struct HueSaturationLightnessParams { + INT hueLevel; + INT saturationLevel; + INT lightnessLevel; +}; + +struct ColorBalanceParams { + INT cyanRed; + INT magentaGreen; + INT yellowBlue; +}; + +struct LevelsParams { + INT highlight; + INT midtone; + INT shadow; +}; + +typedef enum CurveAdjustments { + AdjustExposure, + AdjustDensity, + AdjustContrast, + AdjustHighlight, + AdjustShadow, + AdjustMidtone, + AdjustWhiteSaturation, + AdjustBlackSaturation +} CurveAdjustments; + +typedef enum CurveChannel { + CurveChannelAll, + CurveChannelRed, + CurveChannelGreen, + CurveChannelBlue +} CurveChannel; + +struct ColorCurveParams { + CurveAdjustments adjustment; + CurveChannel channel; + INT adjustValue; +}; + #ifdef __cplusplus extern "C" { #endif
From: Vijay Kiran Kamuju infyquest@gmail.com
--- dlls/gdiplus/gdiplus_private.h | 21 ++++++++++ dlls/gdiplus/image.c | 72 ++++++++++++++++++++++++++++++---- dlls/gdiplus/tests/image.c | 4 +- 3 files changed, 87 insertions(+), 10 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 6f7e72124c2..44d3e6d1000 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -368,6 +368,27 @@ struct GpAdjustableArrowCap{ REAL width; };
+typedef enum EffectType { + NoneEffect, + BlurEffect, + SharpenEffect, + TintEffect, + RedEyeCorrectionEffect, + ColorMatrixEffect, + ColorLUTEffect, + BrightnessContrastEffect, + HueSaturationLightnessEffect, + ColorBalanceEffect, + LevelsEffect, + ColorCurveEffect, +} EffectType; + +typedef struct CGpEffect{ + INT datasize; + void *data; + EffectType type; +} CGpEffect; + struct GpImage{ IWICBitmapDecoder *decoder; IWICBitmapEncoder *encoder; diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 806da0cb696..22bea5b555f 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -5576,14 +5576,70 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBi */ GpStatus WINGDIPAPI GdipCreateEffect(const GUID guid, CGpEffect **effect) { - FIXME("(%s, %p): stub\n", debugstr_guid(&guid), effect); + CGpEffect *ef = NULL; + GpStatus status = Ok;
- if(!effect) + TRACE("(%s, %p)\n", debugstr_guid(&guid), effect); + + if (!effect) return InvalidParameter;
- *effect = NULL; + ef = malloc(sizeof(CGpEffect)); + ef->auxdatasize = 0; + ef->auxdata = NULL;
- return NotImplemented; + if (IsEqualGUID(&guid, &BlurEffectGuid)) + { + ef->type = BlurEffect; + } + else if (IsEqualGUID(&guid, &SharpenEffectGuid)) + { + ef->type = SharpenEffect; + } + else if (IsEqualGUID(&guid, &TintEffectGuid)) + { + ef->type = TintEffect; + } + else if (IsEqualGUID(&guid, &RedEyeCorrectionEffectGuid)) + { + ef->type = RedEyeCorrectionEffect; + } + else if (IsEqualGUID(&guid, &ColorMatrixEffectGuid)) + { + ef->type = ColorMatrixEffect; + } + else if (IsEqualGUID(&guid, &ColorLUTEffectGuid)) + { + ef->type = ColorLUTEffect; + } + else if (IsEqualGUID(&guid, &BrightnessContrastEffectGuid)) + { + ef->type = BrightnessContrastEffect; + } + else if (IsEqualGUID(&guid, &HueSaturationLightnessEffectGuid)) + { + ef->type = HueSaturationLightnessEffect; + } + else if (IsEqualGUID(&guid, &ColorBalanceEffectGuid)) + { + ef->type = ColorBalanceEffect; + } + else if (IsEqualGUID(&guid, &LevelsEffectGuid)) + { + ef->type = LevelsEffect; + } + else if (IsEqualGUID(&guid, &ColorCurveEffectGuid)) + { + ef->type = ColorCurveEffect; + } + else + { + ef->type = NoneEffect; + status = Win32Error; + } + + *effect = ef; + return status; }
/***************************************************************************** @@ -5591,10 +5647,10 @@ GpStatus WINGDIPAPI GdipCreateEffect(const GUID guid, CGpEffect **effect) */ GpStatus WINGDIPAPI GdipDeleteEffect(CGpEffect *effect) { - FIXME("(%p): stub\n", effect); - /* note: According to Jose Roca's GDI+ Docs, this is not implemented - * in Windows's gdiplus */ - return NotImplemented; + TRACE("(%p)\n", effect); + + free(effect); + return Ok; }
/***************************************************************************** diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index 8fc9aa78225..c4a194c14de 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -5429,12 +5429,12 @@ static void test_createeffect(void) expect(InvalidParameter, stat);
stat = pGdipCreateEffect(noneffect, &effect); - todo_wine expect(Win32Error, stat); + expect(Win32Error, stat);
for(i=0; i < ARRAY_SIZE(effectlist); i++) { stat = pGdipCreateEffect(*effectlist[i], &effect); - todo_wine expect(Ok, stat); + expect(Ok, stat); if(stat == Ok) { stat = pGdipDeleteEffect(effect);
From: Vijay Kiran Kamuju infyquest@gmail.com
--- dlls/gdiplus/gdiplus.spec | 2 +- dlls/gdiplus/image.c | 61 ++++++++++++++++++++++++++++++++++++-- dlls/gdiplus/tests/image.c | 55 ++++++++++++++++++++++++++++++++++ include/gdipluseffects.h | 1 + 4 files changed, 116 insertions(+), 3 deletions(-)
diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index 178592e35d9..0f17bb02d4d 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -612,7 +612,7 @@ 612 stdcall GdipGetImageItemData(ptr ptr) 613 stdcall GdipCreateEffect(int128 ptr) 614 stdcall GdipDeleteEffect(ptr) -615 stub GdipGetEffectParameterSize +615 stdcall GdipGetEffectParameterSize(ptr ptr) 616 stub GdipGetEffectParameters 617 stdcall GdipSetEffectParameters(ptr ptr long) 618 stdcall GdipInitializePalette(ptr long long long ptr) diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 22bea5b555f..f8b98de460d 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -5585,8 +5585,8 @@ GpStatus WINGDIPAPI GdipCreateEffect(const GUID guid, CGpEffect **effect) return InvalidParameter;
ef = malloc(sizeof(CGpEffect)); - ef->auxdatasize = 0; - ef->auxdata = NULL; + ef->datasize = 0; + ef->data = NULL;
if (IsEqualGUID(&guid, &BlurEffectGuid)) { @@ -5653,6 +5653,63 @@ GpStatus WINGDIPAPI GdipDeleteEffect(CGpEffect *effect) return Ok; }
+/***************************************************************************** + * GdipGetEffectParameterSize [GDIPLUS.@] + */ +GpStatus WINGDIPAPI GdipGetEffectParameterSize(CGpEffect *effect, UINT *size) +{ + UINT sz = 0; + GpStatus status = Ok; + + TRACE("(%p %p)\n", effect, 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: + status = InvalidParameter; + break; + } + + *size = sz; + return status; +} + /***************************************************************************** * GdipSetEffectParameters [GDIPLUS.@] */ diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index c4a194c14de..abf8fd98625 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -5407,8 +5407,10 @@ static void test_createeffect(void) static const GUID noneffect = { 0xcd0c3d4b, 0xe15e, 0x4cf2, { 0x9e, 0xa8, 0x6e, 0x1d, 0x65, 0x48, 0xc5, 0xa5 } }; GpStatus (WINAPI *pGdipCreateEffect)( const GUID guid, CGpEffect **effect); GpStatus (WINAPI *pGdipDeleteEffect)( CGpEffect *effect); + GpStatus (WINAPI *pGdipGetEffectParameterSize)( CGpEffect *effect, UINT *size); GpStatus stat; CGpEffect *effect; + UINT size, paramsize = 0; HMODULE mod = GetModuleHandleA("gdiplus.dll"); int i; const GUID * const effectlist[] = @@ -5418,6 +5420,7 @@ static void test_createeffect(void)
pGdipCreateEffect = (void*)GetProcAddress( mod, "GdipCreateEffect"); pGdipDeleteEffect = (void*)GetProcAddress( mod, "GdipDeleteEffect"); + pGdipGetEffectParameterSize = (void*)GetProcAddress( mod, "GdipGetEffectParameterSize"); if(!pGdipCreateEffect || !pGdipDeleteEffect) { /* GdipCreateEffect/GdipDeleteEffect was introduced in Windows Vista. */ @@ -5428,15 +5431,67 @@ static void test_createeffect(void) stat = pGdipCreateEffect(BlurEffectGuid, NULL); expect(InvalidParameter, stat);
+ stat = pGdipGetEffectParameterSize(NULL, NULL); + expect(InvalidParameter, stat); + + stat = pGdipGetEffectParameterSize(effect, NULL); + expect(InvalidParameter, stat); + stat = pGdipCreateEffect(noneffect, &effect); expect(Win32Error, stat);
+ stat = pGdipGetEffectParameterSize(effect, &size); + expect(InvalidParameter, stat); + expect(0, size); + for(i=0; i < ARRAY_SIZE(effectlist); i++) { stat = pGdipCreateEffect(*effectlist[i], &effect); expect(Ok, stat); + if(stat == Ok) { + size = 0; + stat = pGdipGetEffectParameterSize(effect, &size); + expect(Ok, stat); + switch(i) + { + case 0: + paramsize = sizeof(struct BlurParams); + break; + case 1: + paramsize = sizeof(struct SharpenParams); + break; + case 2: + paramsize = sizeof(ColorMatrix); + break; + case 3: + paramsize = sizeof(struct ColorLUTParams); + break; + case 4: + paramsize = sizeof(struct BrightnessContrastParams); + break; + case 5: + paramsize = sizeof(struct HueSaturationLightnessParams); + break; + case 6: + paramsize = sizeof(struct LevelsParams); + break; + case 7: + paramsize = sizeof(struct TintParams); + break; + case 8: + paramsize = sizeof(struct ColorBalanceParams); + break; + case 9: + paramsize = sizeof(struct RedEyeCorrectionParams); + break; + case 10: + paramsize = sizeof(struct ColorCurveParams); + break; + } + expect(paramsize, size); + stat = pGdipDeleteEffect(effect); expect(Ok, stat); } diff --git a/include/gdipluseffects.h b/include/gdipluseffects.h index 4100647f7a1..a58d25cb0e3 100644 --- a/include/gdipluseffects.h +++ b/include/gdipluseffects.h @@ -111,6 +111,7 @@ extern "C" {
GpStatus WINGDIPAPI GdipCreateEffect(const GUID guid, CGpEffect **effect); GpStatus WINGDIPAPI GdipDeleteEffect(CGpEffect *effect); +GpStatus WINGDIPAPI GdipGetEffectParameterSize(CGpEffect *effect, UINT *size);
#ifdef __cplusplus }
From: Vijay Kiran Kamuju infyquest@gmail.com
--- dlls/gdiplus/gdiplus_private.h | 13 ++++ dlls/gdiplus/image.c | 109 +++++++++++++++++++++++++++++++-- dlls/gdiplus/tests/image.c | 95 +++++++++++++++++++++++++++- include/gdipluseffects.h | 1 + 4 files changed, 212 insertions(+), 6 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 f8b98de460d..47485f4505c 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -5591,46 +5591,57 @@ GpStatus WINGDIPAPI GdipCreateEffect(const GUID guid, CGpEffect **effect) if (IsEqualGUID(&guid, &BlurEffectGuid)) { ef->type = BlurEffect; + ef->p.blurparams = NULL; } else if (IsEqualGUID(&guid, &SharpenEffectGuid)) { ef->type = SharpenEffect; + ef->p.sharpenparams = NULL; } else if (IsEqualGUID(&guid, &TintEffectGuid)) { ef->type = TintEffect; + ef->p.tintparams = NULL; } else if (IsEqualGUID(&guid, &RedEyeCorrectionEffectGuid)) { ef->type = RedEyeCorrectionEffect; + ef->p.redeyeparams = NULL; } else if (IsEqualGUID(&guid, &ColorMatrixEffectGuid)) { ef->type = ColorMatrixEffect; + ef->p.clrmatrixparams = NULL; } else if (IsEqualGUID(&guid, &ColorLUTEffectGuid)) { ef->type = ColorLUTEffect; + ef->p.clrlutparams = NULL; } else if (IsEqualGUID(&guid, &BrightnessContrastEffectGuid)) { ef->type = BrightnessContrastEffect; + ef->p.brtcntrstparams = NULL; } else if (IsEqualGUID(&guid, &HueSaturationLightnessEffectGuid)) { ef->type = HueSaturationLightnessEffect; + ef->p.huesatliteparams = NULL; } else if (IsEqualGUID(&guid, &ColorBalanceEffectGuid)) { ef->type = ColorBalanceEffect; + ef->p.clrbalanceparams = NULL; } else if (IsEqualGUID(&guid, &LevelsEffectGuid)) { ef->type = LevelsEffect; + ef->p.levelsparams = NULL; } else if (IsEqualGUID(&guid, &ColorCurveEffectGuid)) { ef->type = ColorCurveEffect; + ef->p.clrcurveparams = NULL; } else { @@ -5679,6 +5690,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); @@ -5705,8 +5718,8 @@ GpStatus WINGDIPAPI GdipGetEffectParameterSize(CGpEffect *effect, UINT *size) status = InvalidParameter; break; } - *size = sz; + return status; }
@@ -5716,14 +5729,100 @@ GpStatus WINGDIPAPI GdipGetEffectParameterSize(CGpEffect *effect, UINT *size) 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; + switch (effect->type) + { + case BlurEffect: + paramsize = sizeof(struct BlurParams); + if (paramsize != size) + return InvalidParameter; + effect->p.blurparams = malloc(size); + memcpy(effect->p.blurparams, params, size); + break; + case SharpenEffect: + paramsize = sizeof(struct SharpenParams); + if (paramsize != size) + return InvalidParameter; + effect->p.sharpenparams = malloc(size); + memcpy(effect->p.sharpenparams, params, size); + break; + case TintEffect: + paramsize = sizeof(struct TintParams); + if (paramsize != size) + return InvalidParameter; + effect->p.tintparams = malloc(size); + memcpy(effect->p.tintparams, params, size); + break; + case RedEyeCorrectionEffect: + paramsize = sizeof(struct RedEyeCorrectionParams); + if ((size-paramsize <= 0) || (((size-paramsize)%sizeof(RECT)) != 0)) + return InvalidParameter; + effect->p.redeyeparams = malloc(paramsize); + num = (size-paramsize)/sizeof(RECT); + effect->p.redeyeparams->numberOfAreas = num; + effect->p.redeyeparams->areas = malloc(num*sizeof(RECT)); + memcpy(effect->p.redeyeparams->areas, ((struct RedEyeCorrectionParams *)params)->areas, num*sizeof(RECT)); + break; + case ColorMatrixEffect: + paramsize = sizeof(ColorMatrix); + if (paramsize != size) + return InvalidParameter; + effect->p.clrmatrixparams = malloc(size); + memcpy(effect->p.clrmatrixparams, params, size); + break; + case ColorLUTEffect: + paramsize = sizeof(struct ColorLUTParams); + if (paramsize != size) + return InvalidParameter; + effect->p.clrlutparams = malloc(size); + memcpy(effect->p.clrlutparams, params, size); + break; + case BrightnessContrastEffect: + paramsize = sizeof(struct BrightnessContrastParams); + if (paramsize != size) + return InvalidParameter; + effect->p.brtcntrstparams = malloc(size); + memcpy(effect->p.brtcntrstparams, params, size); + break; + case HueSaturationLightnessEffect: + paramsize = sizeof(struct HueSaturationLightnessParams); + if (paramsize != size) + return InvalidParameter; + effect->p.huesatliteparams = malloc(size); + memcpy(effect->p.huesatliteparams, params, size); + break; + case ColorBalanceEffect: + paramsize = sizeof(struct ColorBalanceParams); + if (paramsize != size) + return InvalidParameter; + effect->p.clrbalanceparams = malloc(size); + memcpy(effect->p.clrbalanceparams, params, size); + break; + case LevelsEffect: + paramsize = sizeof(struct LevelsParams); + if (paramsize != size) + return InvalidParameter; + effect->p.levelsparams = malloc(size); + memcpy(effect->p.levelsparams, params, size); + break; + case ColorCurveEffect: + paramsize = sizeof(struct ColorCurveParams); + if (paramsize != size) + return InvalidParameter; + effect->p.clrcurveparams = malloc(size); + memcpy(effect->p.clrcurveparams, params, size); + break; + default: + return InvalidParameter; + } + + return Ok; }
/***************************************************************************** diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index abf8fd98625..5690f6bb27e 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -5408,19 +5408,34 @@ 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, paramsize = 0; + void *params = NULL; HMODULE mod = GetModuleHandleA("gdiplus.dll"); - int i; + int i, j, k; const GUID * const effectlist[] = {&BlurEffectGuid, &SharpenEffectGuid, &ColorMatrixEffectGuid, &ColorLUTEffectGuid, &BrightnessContrastEffectGuid, &HueSaturationLightnessEffectGuid, &LevelsEffectGuid, &TintEffectGuid, &ColorBalanceEffectGuid, &RedEyeCorrectionEffectGuid, &ColorCurveEffectGuid}; + struct BlurParams blur; + struct SharpenParams sharpen; + ColorMatrix matrix; + struct ColorLUTParams clut; + struct BrightnessContrastParams bc; + struct HueSaturationLightnessParams hsl; + struct LevelsParams lvl; + struct TintParams tint; + struct ColorBalanceParams cbal; + struct RedEyeCorrectionParams redi; + struct ColorCurveParams ccurve; + RECT rects[2];
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. */ @@ -5434,15 +5449,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); + stat = pGdipCreateEffect(noneffect, &effect); expect(Win32Error, stat);
stat = pGdipGetEffectParameterSize(effect, &size); expect(InvalidParameter, stat); expect(0, size); + 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(effectlist); i++) { @@ -5458,38 +5485,104 @@ static void test_createeffect(void) { case 0: paramsize = sizeof(struct BlurParams); + expect(paramsize, size); + blur.radius = 2.0; + blur.expandEdge = TRUE; + stat = pGdipSetEffectParameters(effect, (void *)&blur, 5); + expect(InvalidParameter, stat); + stat = pGdipSetEffectParameters(effect, (void *)&blur, paramsize); break; case 1: paramsize = sizeof(struct SharpenParams); + expect(paramsize, size); + sharpen.radius = 5.0; + sharpen.amount = 2; + stat = pGdipSetEffectParameters(effect, (void *)&sharpen, paramsize); break; case 2: paramsize = sizeof(ColorMatrix); + expect(paramsize, size); + for (j = 0; j < 5; j++) { + for (k = 0; k < 5; k++) { + matrix.m[j][k] = (float) j+1; + } + } + stat = pGdipSetEffectParameters(effect, (void *)&matrix, paramsize); break; case 3: paramsize = sizeof(struct ColorLUTParams); + expect(paramsize, size); + for (j = 0; j < sizeof(ColorChannelLUT); j++) + { + clut.lutB[j] = j%8; + clut.lutG[j] = j%16; + clut.lutR[j] = j%4; + clut.lutA[j] = 0; + } + stat = pGdipSetEffectParameters(effect, (void *)&clut, paramsize); break; case 4: paramsize = sizeof(struct BrightnessContrastParams); + expect(paramsize, size); + bc.brightnessLevel = 75; + bc.contrastLevel = 50; + stat = pGdipSetEffectParameters(effect, (void *)&bc, paramsize); break; case 5: paramsize = sizeof(struct HueSaturationLightnessParams); + expect(paramsize, size); + hsl.hueLevel = 50; + hsl.saturationLevel = 50; + hsl.lightnessLevel = 50; + stat = pGdipSetEffectParameters(effect, (void *)&hsl, paramsize); break; case 6: paramsize = sizeof(struct LevelsParams); + expect(paramsize, size); + lvl.highlight = 50; + lvl.midtone = 50; + lvl.shadow = 5; + stat = pGdipSetEffectParameters(effect, (void *)&lvl, paramsize); break; case 7: paramsize = sizeof(struct TintParams); + expect(paramsize, size); + tint.hue = 20; + tint.amount = 5; + stat = pGdipSetEffectParameters(effect, (void *)&tint, paramsize); break; case 8: paramsize = sizeof(struct ColorBalanceParams); + expect(paramsize, size); + cbal.cyanRed = 50; + cbal.magentaGreen = 50; + cbal.yellowBlue = 50; + stat = pGdipSetEffectParameters(effect, (void *)&cbal, paramsize); break; case 9: paramsize = sizeof(struct RedEyeCorrectionParams); + expect(paramsize, size); + SetRect(&rects[0], 0, 0, 75, 75); + SetRect(&rects[1], -32, -32, 32, 32); + redi.numberOfAreas = 2; + redi.areas = rects; + stat = pGdipSetEffectParameters(effect, (void *)&redi, paramsize); + expect(InvalidParameter, stat); + paramsize = paramsize + (2*sizeof(RECT)); + stat = pGdipSetEffectParameters(effect, (void *)&redi, paramsize); break; case 10: paramsize = sizeof(struct ColorCurveParams); + expect(paramsize, size); + ccurve.adjustment = AdjustExposure; + ccurve.channel = CurveChannelAll; + ccurve.adjustValue = 5; + stat = pGdipSetEffectParameters(effect, (void *)&ccurve, paramsize); break; } + expect(Ok, stat); + size = 0; + stat = pGdipGetEffectParameterSize(effect, &size); expect(paramsize, size);
stat = pGdipDeleteEffect(effect); 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 }
From: Vijay Kiran Kamuju infyquest@gmail.com
--- dlls/gdiplus/gdiplus.spec | 2 +- dlls/gdiplus/image.c | 58 ++++++++++++++++++++++++++++++++++++++ dlls/gdiplus/tests/image.c | 17 +++++++++++ include/gdipluseffects.h | 1 + 4 files changed, 77 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 47485f4505c..6c3fd9ff083 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -5723,6 +5723,64 @@ GpStatus WINGDIPAPI GdipGetEffectParameterSize(CGpEffect *effect, UINT *size) return status; }
+/***************************************************************************** + * GdipGetEffectParameters [GDIPLUS.@] + */ +GpStatus WINGDIPAPI GdipGetEffectParameters(CGpEffect *effect, + UINT *size, VOID *params) +{ + GpStatus stat; + + TRACE("(%p,%p,%p)\n", effect, size, params); + if (!effect || !params || !size) + return InvalidParameter; + + stat = GdipGetEffectParameterSize(effect, size); + if (stat) + { + switch (effect->type) + { + case BlurEffect: + params = &effect->p.blurparams; + break; + case SharpenEffect: + params = &effect->p.sharpenparams; + break; + case TintEffect: + params = &effect->p.tintparams; + break; + case RedEyeCorrectionEffect: + params = &effect->p.redeyeparams; + break; + case ColorMatrixEffect: + params = &effect->p.clrmatrixparams; + break; + case ColorLUTEffect: + params = &effect->p.clrlutparams; + break; + case BrightnessContrastEffect: + params = &effect->p.brtcntrstparams; + break; + case HueSaturationLightnessEffect: + params = &effect->p.huesatliteparams; + break; + case ColorBalanceEffect: + params = &effect->p.clrbalanceparams; + break; + case LevelsEffect: + params = &effect->p.levelsparams; + break; + case ColorCurveEffect: + params = &effect->p.clrcurveparams; + break; + default: + return InvalidParameter; + } + stat = Ok; + } + return stat; +} + /***************************************************************************** * GdipSetEffectParameters [GDIPLUS.@] */ diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index 5690f6bb27e..d5788499d94 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -5408,6 +5408,7 @@ 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, UINT *size, VOID *params); GpStatus (WINAPI *pGdipSetEffectParameters)( CGpEffect *effect, const VOID *params, const UINT size); GpStatus stat; CGpEffect *effect; @@ -5435,6 +5436,7 @@ static void test_createeffect(void) pGdipCreateEffect = (void*)GetProcAddress( mod, "GdipCreateEffect"); pGdipDeleteEffect = (void*)GetProcAddress( mod, "GdipDeleteEffect"); pGdipGetEffectParameterSize = (void*)GetProcAddress( mod, "GdipGetEffectParameterSize"); + pGdipGetEffectParameters = (void*)GetProcAddress( mod, "GdipGetEffectParameters"); pGdipSetEffectParameters = (void*)GetProcAddress( mod, "GdipSetEffectParameters"); if(!pGdipCreateEffect || !pGdipDeleteEffect) { @@ -5452,12 +5454,21 @@ static void test_createeffect(void) stat = pGdipSetEffectParameters(NULL, NULL, 0); expect(InvalidParameter, stat);
+ stat = pGdipGetEffectParameters(NULL, NULL, NULL); + expect(InvalidParameter, stat); + stat = pGdipGetEffectParameterSize(effect, NULL); expect(InvalidParameter, stat);
stat = pGdipSetEffectParameters(effect, params, 0); expect(InvalidParameter, stat);
+ stat = pGdipGetEffectParameters(effect, &size, NULL); + expect(InvalidParameter, stat); + + stat = pGdipGetEffectParameters(effect, &size, params); + expect(InvalidParameter, stat); + stat = pGdipCreateEffect(noneffect, &effect); expect(Win32Error, stat);
@@ -5584,6 +5595,12 @@ static void test_createeffect(void) size = 0; stat = pGdipGetEffectParameterSize(effect, &size); expect(paramsize, size); + size = 0; + params = malloc(paramsize); + stat = pGdipGetEffectParameters(effect, &size, params); + expect(Ok, stat); + expect(paramsize, size); + free(params);
stat = pGdipDeleteEffect(effect); expect(Ok, stat); diff --git a/include/gdipluseffects.h b/include/gdipluseffects.h index 2b94479f7f5..17a07726f33 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 GdipGetEffectParameters(CGpEffect *effect, UINT *size, VOID *params); GpStatus WINGDIPAPI GdipSetEffectParameters(CGpEffect *effect, const VOID *params, const UINT size);
#ifdef __cplusplus