Martin Petricek : gdiplus: Support for indexed formats in GdipBitmapSetPixel.
Alexandre Julliard
julliard at winehq.org
Wed Jan 12 13:16:54 CST 2011
Module: wine
Branch: master
Commit: ee3c1790265eeb7fc90ef89e20c1fa87b7b006d9
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ee3c1790265eeb7fc90ef89e20c1fa87b7b006d9
Author: Martin Petricek <tux at centrum.cz>
Date: Wed Jan 12 04:34:47 2011 +0100
gdiplus: Support for indexed formats in GdipBitmapSetPixel.
---
dlls/gdiplus/image.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
dlls/gdiplus/tests/image.c | 6 ++--
2 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index 69f5865..a69046d 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -296,6 +296,53 @@ GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y,
return Ok;
}
+static inline UINT get_palette_index(BYTE r, BYTE g, BYTE b, BYTE a, GpBitmap* bitmap) {
+ BYTE index = 0;
+ int best_distance = 0x7fff;
+ int distance;
+ int i;
+ /* This algorithm scans entire pallete,
+ computes difference from desired color (all color components have equal weight)
+ and returns the index of color with least difference.
+
+ Note: Maybe it could be replaced with a better algorithm for better image quality
+ and performance, though better algorithm would probably need some pre-built lookup
+ tables and thus may actually be slower if this method is called only few times per
+ every image.
+ */
+ for(i=0;i<bitmap->image.palette_size;i++) {
+ ARGB color=bitmap->image.palette_entries[i];
+ distance=abs(b-(color & 0xff)) + abs(g-(color>>8 & 0xff)) + abs(r-(color>>16 & 0xff)) + abs(a-(color>>24 & 0xff));
+ if (distance<best_distance) {
+ best_distance=distance;
+ index=i;
+ }
+ }
+ return index;
+}
+
+static inline void setpixel_8bppIndexed(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x, GpBitmap* bitmap)
+{
+ BYTE index = get_palette_index(r,g,b,a,bitmap);
+ row[x]=index;
+}
+
+static inline void setpixel_1bppIndexed(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x, GpBitmap* bitmap)
+{
+ row[x/8] = (row[x/8] & ~(1<<(7-x%8))) | (get_palette_index(r,g,b,a,bitmap)<<(7-x%8));
+}
+
+static inline void setpixel_4bppIndexed(BYTE r, BYTE g, BYTE b, BYTE a,
+ BYTE *row, UINT x, GpBitmap* bitmap)
+{
+ if (x & 1)
+ row[x/2] = (row[x/2] & 0xf0) | get_palette_index(r,g,b,a,bitmap);
+ else
+ row[x/2] = (row[x/2] & 0x0f) | get_palette_index(r,g,b,a,bitmap)<<4;
+}
+
static inline void setpixel_16bppGrayScale(BYTE r, BYTE g, BYTE b, BYTE a,
BYTE *row, UINT x)
{
@@ -434,6 +481,15 @@ GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y,
case PixelFormat64bppPARGB:
setpixel_64bppPARGB(r,g,b,a,row,x);
break;
+ case PixelFormat8bppIndexed:
+ setpixel_8bppIndexed(r,g,b,a,row,x,bitmap);
+ break;
+ case PixelFormat4bppIndexed:
+ setpixel_4bppIndexed(r,g,b,a,row,x,bitmap);
+ break;
+ case PixelFormat1bppIndexed:
+ setpixel_1bppIndexed(r,g,b,a,row,x,bitmap);
+ break;
default:
FIXME("not implemented for format 0x%x\n", bitmap->format);
return NotImplemented;
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index b2b1a0f..989e0bb 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -1568,7 +1568,7 @@ static void test_palette(void)
expect(0xff000000, color);
stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff);
- todo_wine ok((stat == Ok) ||
+ ok((stat == Ok) ||
broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
if (stat == Ok)
@@ -1601,7 +1601,7 @@ static void test_palette(void)
expect(0xff000000, color);
stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff);
- todo_wine ok((stat == Ok) ||
+ ok((stat == Ok) ||
broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
if (stat == Ok)
@@ -1634,7 +1634,7 @@ static void test_palette(void)
expect(0xff000000, color);
stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc);
- todo_wine ok((stat == Ok) ||
+ ok((stat == Ok) ||
broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
if (stat == Ok)
More information about the wine-cvs
mailing list