Vincent Povirk : gdiplus: Implement color transforms.
Alexandre Julliard
julliard at winehq.org
Mon Mar 28 14:21:59 CDT 2011
Module: wine
Branch: master
Commit: 805f0321ebffe0db2d39f414c0f19c21958bb3f6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=805f0321ebffe0db2d39f414c0f19c21958bb3f6
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Thu Mar 24 16:50:05 2011 -0500
gdiplus: Implement color transforms.
---
dlls/gdiplus/graphics.c | 65 +++++++++++++++++++++++++++++++++++++++++--
dlls/gdiplus/tests/image.c | 30 +++++++++++++++++---
2 files changed, 88 insertions(+), 7 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 7d2dbcd..840825a 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -331,6 +331,45 @@ static ARGB blend_line_gradient(GpLineGradient* brush, REAL position)
}
}
+static ARGB transform_color(ARGB color, const ColorMatrix *matrix)
+{
+ REAL val[5], res[4];
+ int i, j;
+ unsigned char a, r, g, b;
+
+ val[0] = ((color >> 16) & 0xff) / 255.0; /* red */
+ val[1] = ((color >> 8) & 0xff) / 255.0; /* green */
+ val[2] = (color & 0xff) / 255.0; /* blue */
+ val[3] = ((color >> 24) & 0xff) / 255.0; /* alpha */
+ val[4] = 1.0; /* translation */
+
+ for (i=0; i<4; i++)
+ {
+ res[i] = 0.0;
+
+ for (j=0; j<5; j++)
+ res[i] += matrix->m[j][i] * val[j];
+ }
+
+ a = min(max(floorf(res[3]*255.0), 0.0), 255.0);
+ r = min(max(floorf(res[0]*255.0), 0.0), 255.0);
+ g = min(max(floorf(res[1]*255.0), 0.0), 255.0);
+ b = min(max(floorf(res[2]*255.0), 0.0), 255.0);
+
+ return (a << 24) | (r << 16) | (g << 8) | b;
+}
+
+static int color_is_gray(ARGB color)
+{
+ unsigned char r, g, b;
+
+ r = (color >> 16) & 0xff;
+ g = (color >> 8) & 0xff;
+ b = color & 0xff;
+
+ return (r == g) && (g == b);
+}
+
static void apply_image_attributes(const GpImageAttributes *attributes, LPBYTE data,
UINT width, UINT height, INT stride, ColorAdjustType type)
{
@@ -400,9 +439,29 @@ static void apply_image_attributes(const GpImageAttributes *attributes, LPBYTE d
if (attributes->colormatrices[type].enabled ||
attributes->colormatrices[ColorAdjustTypeDefault].enabled)
{
- static int fixme;
- if (!fixme++)
- FIXME("Color transforms not implemented\n");
+ const struct color_matrix *colormatrices;
+
+ if (attributes->colormatrices[type].enabled)
+ colormatrices = &attributes->colormatrices[type];
+ else
+ colormatrices = &attributes->colormatrices[ColorAdjustTypeDefault];
+
+ for (x=0; x<width; x++)
+ for (y=0; y<height; y++)
+ {
+ ARGB *src_color;
+ src_color = (ARGB*)(data + stride * y + sizeof(ARGB) * x);
+
+ if (colormatrices->flags == ColorMatrixFlagsDefault ||
+ !color_is_gray(*src_color))
+ {
+ *src_color = transform_color(*src_color, &colormatrices->colormatrix);
+ }
+ else if (colormatrices->flags == ColorMatrixFlagsAltGray)
+ {
+ *src_color = transform_color(*src_color, &colormatrices->graymatrix);
+ }
+ }
}
if (attributes->gamma_enabled[type] ||
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index 71a99ea..cbae047 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -1923,6 +1923,12 @@ static void test_colormatrix(void)
{0.0,0.0,1.0,0.0,0.0},
{0.0,0.0,0.0,1.0,0.0},
{0.0,0.0,0.0,0.0,1.0}}};
+ const ColorMatrix asymmetric = {{
+ {0.0,1.0,0.0,0.0,0.0},
+ {0.0,0.0,1.0,0.0,0.0},
+ {0.0,0.0,0.0,1.0,0.0},
+ {1.0,0.0,0.0,0.0,0.0},
+ {0.0,0.0,0.0,0.0,1.0}}};
GpBitmap *bitmap1, *bitmap2;
GpGraphics *graphics;
ARGB color;
@@ -1983,13 +1989,13 @@ static void test_colormatrix(void)
TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
expect(Ok, stat);
- stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
+ stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap1);
expect(Ok, stat);
- stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
+ stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap2);
expect(Ok, stat);
- stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff40ffff);
+ stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff40ccee);
expect(Ok, stat);
stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
@@ -2001,7 +2007,23 @@ static void test_colormatrix(void)
stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
expect(Ok, stat);
- todo_wine expect(0xff80ffff, color);
+ expect(0xff80ccee, color);
+
+ colormatrix = asymmetric;
+ stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
+ TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
+ expect(Ok, stat);
+
+ stat = GdipBitmapSetPixel(bitmap2, 0, 0, 0);
+ expect(Ok, stat);
+
+ stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
+ UnitPixel, imageattr, NULL, NULL);
+ expect(Ok, stat);
+
+ stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
+ expect(Ok, stat);
+ ok(color_match(0xeeff40cc, color, 3), "expected 0xeeff40cc, got 0x%08x\n", color);
GdipDeleteGraphics(graphics);
GdipDisposeImage((GpImage*)bitmap1);
More information about the wine-cvs
mailing list