gdiplus: Implement color transforms.
This commit is contained in:
parent
1b5602e59c
commit
805f0321eb
|
@ -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] ||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue