[2/3] gdiplus: Split alpha_blend_bmp_pixels into separate loops per pixel format.

Vincent Povirk madewokherd at gmail.com
Fri Sep 19 11:25:24 CDT 2014


-------------- next part --------------
From 444dc51e0d73c7f25146d7821e886af3fd8342d0 Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Thu, 18 Sep 2014 13:14:43 -0500
Subject: [PATCH 2/3] gdiplus: Split alpha_blend_bmp_pixels into separate loops
 per pixel format.

---
 dlls/gdiplus/gdiplus_private.h |   4 ++
 dlls/gdiplus/graphics.c        |  16 ++-----
 dlls/gdiplus/image.c           | 100 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+), 13 deletions(-)

diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index b001dbc..ad91eef 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -127,6 +127,10 @@ extern GpStatus convert_pixels(INT width, INT height,
     INT dst_stride, BYTE *dst_bits, PixelFormat dst_format,
     INT src_stride, const BYTE *src_bits, PixelFormat src_format, ColorPalette *palette) DECLSPEC_HIDDEN;
 
+extern GpStatus compose_pixels(INT dst_x, INT dst_y, INT width, INT height,
+    INT dst_stride, BYTE *dst_bits, PixelFormat dst_format, ColorPalette *dst_palette,
+    INT src_stride, const BYTE *src_bits) DECLSPEC_HIDDEN;
+
 struct GpMatrix{
     REAL matrix[6];
 };
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 169d92c..0b892b7 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -358,20 +358,10 @@ static GpStatus alpha_blend_bmp_pixels(GpGraphics *graphics, INT dst_x, INT dst_
     const BYTE *src, INT src_width, INT src_height, INT src_stride)
 {
     GpBitmap *dst_bitmap = (GpBitmap*)graphics->image;
-    INT x, y;
 
-    for (x=0; x<src_width; x++)
-    {
-        for (y=0; y<src_height; y++)
-        {
-            ARGB dst_color, src_color;
-            GdipBitmapGetPixel(dst_bitmap, x+dst_x, y+dst_y, &dst_color);
-            src_color = ((ARGB*)(src + src_stride * y))[x];
-            GdipBitmapSetPixel(dst_bitmap, x+dst_x, y+dst_y, color_over(dst_color, src_color));
-        }
-    }
-
-    return Ok;
+    return compose_pixels(dst_x, dst_y, src_width, src_height,
+        dst_bitmap->stride, dst_bitmap->bits, dst_bitmap->format, dst_bitmap->image.palette,
+        src_stride, src);
 }
 
 static GpStatus alpha_blend_hdc_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index 0564f33..8511e3e 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -1027,6 +1027,106 @@ GpStatus convert_pixels(INT width, INT height,
     return NotImplemented;
 }
 
+GpStatus compose_pixels(INT dst_x, INT dst_y, INT width, INT height,
+    INT dst_stride, BYTE *dst_bits, PixelFormat dst_format, ColorPalette *dst_palette,
+    INT src_stride, const BYTE *src_bits)
+{
+    INT x, y;
+
+#define compose_rgb(getpixel_function, setpixel_function) do { \
+    for (y=0; y<height; y++) \
+        for (x=0; x<width; x++) { \
+            BYTE rs, gs, bs, as; \
+            BYTE rd, gd, bd, ad; \
+            BYTE rf, gf, bf, af; \
+            BYTE dmult; \
+            getpixel_32bppARGB(&rs, &gs, &bs, &as, src_bits+src_stride*y, x); \
+            if (as == 0) continue; \
+            getpixel_function(&rd, &gd, &bd, &ad, dst_bits+dst_stride*(y+dst_y), x+dst_x); \
+            dmult = ad * (255 - as) / 255; \
+            if (dmult == 0) { \
+                setpixel_function(rs, gs, bs, as, dst_bits+dst_stride*(y+dst_y), x+dst_x); \
+                continue; \
+            } \
+            af = as + dmult; \
+            rf = (rs * as + rd * dmult) / af; \
+            gf = (gs * as + gd * dmult) / af; \
+            bf = (bs * as + bd * dmult) / af; \
+            setpixel_function(rf, gf, bf, af, dst_bits+dst_stride*(y+dst_y), x+dst_x); \
+        } \
+    return Ok; \
+} while (0);
+
+#define compose_indexed(getpixel_function, setpixel_function) do { \
+    for (y=0; y<height; y++) \
+        for (x=0; x<width; x++) { \
+            BYTE rs, gs, bs, as; \
+            ARGB argb; \
+            BYTE *color = (BYTE *)&argb; \
+            BYTE index; \
+            BYTE rd, gd, bd, ad; \
+            BYTE rf, gf, bf, af; \
+            BYTE dmult; \
+            getpixel_32bppARGB(&rs, &gs, &bs, &as, src_bits+src_stride*y, x); \
+            if (as == 0) continue; \
+            getpixel_function(&index, dst_bits+dst_stride*(y+dst_y), x+dst_x); \
+            argb = (dst_palette && index < dst_palette->Count) ? dst_palette->Entries[index] : 0; \
+            rd = color[2]; \
+            bd = color[1]; \
+            gd = color[0]; \
+            ad = color[3]; \
+            dmult = ad * (255 - as) / 255; \
+            if (dmult == 0) { \
+                setpixel_function(rs, gs, bs, as, dst_bits+dst_stride*(y+dst_y), x+dst_x, dst_palette); \
+                continue; \
+            } \
+            af = as + dmult; \
+            rf = (rs * as + rd * dmult) / af; \
+            gf = (gs * as + gd * dmult) / af; \
+            bf = (bs * as + bd * dmult) / af; \
+            setpixel_function(rf, gf, bf, af, dst_bits+dst_stride*(y+dst_y), x+dst_x, dst_palette); \
+        } \
+    return Ok; \
+} while (0);
+
+    switch (dst_format)
+    {
+    case PixelFormat1bppIndexed:
+        compose_indexed(getpixel_1bppIndexed, setpixel_1bppIndexed);
+    case PixelFormat4bppIndexed:
+        compose_indexed(getpixel_4bppIndexed, setpixel_4bppIndexed);
+    case PixelFormat8bppIndexed:
+        compose_indexed(getpixel_8bppIndexed, setpixel_8bppIndexed);
+    case PixelFormat16bppGrayScale:
+        compose_rgb(getpixel_16bppGrayScale, setpixel_16bppGrayScale);
+    case PixelFormat16bppRGB555:
+        compose_rgb(getpixel_16bppRGB555, setpixel_16bppRGB555);
+    case PixelFormat16bppRGB565:
+        compose_rgb(getpixel_16bppRGB565, setpixel_16bppRGB565);
+    case PixelFormat16bppARGB1555:
+        compose_rgb(getpixel_16bppARGB1555, setpixel_16bppARGB1555);
+    case PixelFormat24bppRGB:
+        compose_rgb(getpixel_24bppRGB, setpixel_24bppRGB);
+    case PixelFormat32bppRGB:
+        compose_rgb(getpixel_32bppRGB, setpixel_32bppRGB);
+    case PixelFormat32bppARGB:
+        compose_rgb(getpixel_32bppARGB, setpixel_32bppARGB);
+    case PixelFormat32bppPARGB:
+        compose_rgb(getpixel_32bppPARGB, setpixel_32bppPARGB);
+    case PixelFormat48bppRGB:
+        compose_rgb(getpixel_48bppRGB, setpixel_48bppRGB);
+    case PixelFormat64bppARGB:
+        compose_rgb(getpixel_64bppARGB, setpixel_64bppARGB);
+    default:
+        break;
+    }
+
+#undef compose_indexed
+#undef compose_rgb
+
+    return NotImplemented;
+}
+
 /* This function returns a pointer to an array of pixels that represents the
  * bitmap. The *entire* bitmap is locked according to the lock mode specified by
  * flags.  It is correct behavior that a user who calls this function with write
-- 
1.9.1



More information about the wine-patches mailing list