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