Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/image.c | 13 +++++++++---- dlls/gdiplus/tests/image.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 9fa2aaee95..29fba1a9c1 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -239,12 +239,17 @@ static inline void getpixel_32bppPARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, { *a = row[x*4+3]; if (*a == 0) - *r = *g = *b = 0; + { + *r = row[x*4+2]; + *g = row[x*4+1]; + *b = row[x*4]; + } else { - *r = row[x*4+2] * 255 / *a; - *g = row[x*4+1] * 255 / *a; - *b = row[x*4] * 255 / *a; + DWORD scaled_q = (255 << 15) / *a; + *r = (row[x*4+2] > *a) ? 0xff : (row[x*4+2] * scaled_q) >> 15; + *g = (row[x*4+1] > *a) ? 0xff : (row[x*4+1] * scaled_q) >> 15; + *b = (row[x*4] > *a) ? 0xff : (row[x*4] * scaled_q) >> 15; } }
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index 5923611163..7334a756ae 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -4806,6 +4806,39 @@ static void test_ARGB_conversion(void) GdipDisposeImage((GpImage *)bitmap); }
+static void test_PARGB_conversion(void) +{ + BYTE pargb[8] = { 0x62,0x77,0x99,0x77, 0x62,0x77,0x99,0 }; + BYTE argb[8] = { 0xd1,0xfe,0xff,0x77, 0x62,0x77,0x99,0 }; + BYTE *bits; + GpBitmap *bitmap; + BitmapData data; + GpStatus status; + int match; + + status = GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppPARGB, pargb, &bitmap); + expect(Ok, status); + + status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat32bppARGB, &data); + expect(Ok, status); + ok(data.Width == 2, "expected 2, got %d\n", data.Width); + ok(data.Height == 1, "expected 1, got %d\n", data.Height); + ok(data.Stride == 8, "expected 8, got %d\n", data.Stride); + ok(data.PixelFormat == PixelFormat32bppARGB, "expected PixelFormat32bppARGB, got %d\n", data.PixelFormat); + match = !memcmp(data.Scan0, argb, sizeof(argb)); + ok(match, "bits don't match\n"); + if (!match) + { + bits = data.Scan0; + trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppARGB, + bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]); + } + status = GdipBitmapUnlockBits(bitmap, &data); + expect(Ok, status); + + GdipDisposeImage((GpImage *)bitmap); +} +
static void test_CloneBitmapArea(void) { @@ -5626,6 +5659,7 @@ START_TEST(image) test_supported_encoders(); test_CloneBitmapArea(); test_ARGB_conversion(); + test_PARGB_conversion(); test_DrawImage_scale(); test_image_format(); test_DrawImage();
Applies fix from d23bfd8dfc74a1955a0270feaf07ccd7a23a723a to setpixel_32bppPARGB.
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/image.c | 6 +++--- dlls/gdiplus/tests/image.c | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 29fba1a9c1..dcdc49c6d6 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -459,9 +459,9 @@ static inline void setpixel_32bppARGB(BYTE r, BYTE g, BYTE b, BYTE a, static inline void setpixel_32bppPARGB(BYTE r, BYTE g, BYTE b, BYTE a, BYTE *row, UINT x) { - r = r * a / 255; - g = g * a / 255; - b = b * a / 255; + r = (r * a + 127) / 255; + g = (g * a + 127) / 255; + b = (b * a + 127) / 255; *((DWORD*)(row)+x) = (a<<24)|(r<<16)|(g<<8)|b; }
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index 7334a756ae..06fd3c061a 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -4810,6 +4810,7 @@ static void test_PARGB_conversion(void) { BYTE pargb[8] = { 0x62,0x77,0x99,0x77, 0x62,0x77,0x99,0 }; BYTE argb[8] = { 0xd1,0xfe,0xff,0x77, 0x62,0x77,0x99,0 }; + BYTE pargb2[8] = { 0x01,0x01,0x00,0x01, 0xfe,0x7f,0x7f,0xfe }; BYTE *bits; GpBitmap *bitmap; BitmapData data; @@ -4836,6 +4837,28 @@ static void test_PARGB_conversion(void) status = GdipBitmapUnlockBits(bitmap, &data); expect(Ok, status);
+ /* Testing SetPixel 32-bit ARGB to PARGB */ + status = GdipBitmapSetPixel(bitmap, 0, 0, 0x017f80ff); + expect(Ok, status); + status = GdipBitmapSetPixel(bitmap, 1, 0, 0xfe7f80ff); + expect(Ok, status); + status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat32bppPARGB, &data); + expect(Ok, status); + ok(data.Width == 2, "expected 2, got %d\n", data.Width); + ok(data.Height == 1, "expected 1, got %d\n", data.Height); + ok(data.Stride == 8, "expected 8, got %d\n", data.Stride); + ok(data.PixelFormat == PixelFormat32bppPARGB, "expected PixelFormat32bppPARGB, got %d\n", data.PixelFormat); + match = !memcmp(data.Scan0, pargb2, sizeof(pargb2)); + ok(match, "bits don't match\n"); + if (!match) + { + bits = data.Scan0; + trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB, + bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]); + } + status = GdipBitmapUnlockBits(bitmap, &data); + expect(Ok, status); + GdipDisposeImage((GpImage *)bitmap); }
Signed-off-by: Vincent Povirk vincent@codeweavers.com