gdiplus: Implement color transforms.

oldstable
Vincent Povirk 2011-03-24 16:50:05 -05:00 committed by Alexandre Julliard
parent 1b5602e59c
commit 805f0321eb
2 changed files with 88 additions and 7 deletions

View File

@ -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] ||

View File

@ -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);