[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