Alexandre Julliard : winex11: Set all the bitmap padding to 0 in GetImage.
Alexandre Julliard
julliard at winehq.org
Fri Jul 15 11:45:15 CDT 2011
Module: wine
Branch: master
Commit: 678400b88719b5254185c2b5fd46cbb0882e7f03
URL: http://source.winehq.org/git/wine.git/?a=commit;h=678400b88719b5254185c2b5fd46cbb0882e7f03
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Jul 15 13:49:36 2011 +0200
winex11: Set all the bitmap padding to 0 in GetImage.
---
dlls/winex11.drv/bitblt.c | 66 +++++++++++++++++++++++++++++++++++++++-----
1 files changed, 58 insertions(+), 8 deletions(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c
index f252e42..95600b0 100644
--- a/dlls/winex11.drv/bitblt.c
+++ b/dlls/winex11.drv/bitblt.c
@@ -480,6 +480,24 @@ static const unsigned char bit_swap[256] =
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
+#ifdef WORDS_BIGENDIAN
+static const unsigned int zeropad_masks[32] =
+{
+ 0xffffffff, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
+ 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
+ 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
+ 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe
+};
+#else
+static const unsigned int zeropad_masks[32] =
+{
+ 0xffffffff, 0x00000080, 0x000000c0, 0x000000e0, 0x000000f0, 0x000000f8, 0x000000fc, 0x000000fe,
+ 0x000000ff, 0x000080ff, 0x0000c0ff, 0x0000e0ff, 0x0000f0ff, 0x0000f8ff, 0x0000fcff, 0x0000feff,
+ 0x0000ffff, 0x0080ffff, 0x00c0ffff, 0x00e0ffff, 0x00f0ffff, 0x00f8ffff, 0x00fcffff, 0x00feffff,
+ 0x00ffffff, 0x80ffffff, 0xc0ffffff, 0xe0ffffff, 0xf0ffffff, 0xf8ffffff, 0xfcffffff, 0xfeffffff
+};
+#endif
+
#ifdef BITBLT_TEST /* Opcodes test */
static int do_bitop( int s, int d, int rop )
@@ -1637,12 +1655,19 @@ static void set_color_info( const ColorShifts *color_shifts, BITMAPINFO *info )
}
/* copy the image bits, fixing up alignment and byte swapping as necessary */
-static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts, XImage *image,
- const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits )
+ DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts, XImage *image,
+ const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits,
+ unsigned int zeropad_mask )
{
+#ifdef WORDS_BIGENDIAN
+ static const int client_byte_order = MSBFirst;
+#else
+ static const int client_byte_order = LSBFirst;
+#endif
BOOL need_byteswap;
int x, y, height = abs(info->bmiHeader.biHeight);
int width_bytes = image->bytes_per_line;
+ int padding_pos;
unsigned char *src, *dst;
switch (info->bmiHeader.biBitCount)
@@ -1655,7 +1680,7 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
break;
case 16:
case 32:
- need_byteswap = (image->byte_order != LSBFirst);
+ need_byteswap = (image->byte_order != client_byte_order);
break;
case 24:
need_byteswap = ((image->byte_order == LSBFirst && color_shifts->logicalBlue.shift == 16) ||
@@ -1666,7 +1691,10 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
break;
}
- if ((need_byteswap && !src_bits->is_copy) || (width_bytes & 3) || (info->bmiHeader.biHeight > 0))
+ if ((need_byteswap && !src_bits->is_copy) || /* need to swap bytes */
+ (zeropad_mask != ~0u && !src_bits->is_copy) || /* need to clear padding bytes */
+ (width_bytes & 3) || /* need to fixup line alignment */
+ (info->bmiHeader.biHeight > 0)) /* need to flip vertically */
{
width_bytes = (width_bytes + 3) & ~3;
info->bmiHeader.biSizeImage = height * width_bytes;
@@ -1683,11 +1711,12 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
dst_bits->offset = src_bits->offset;
dst_bits->is_copy = src_bits->is_copy;
dst_bits->free = NULL;
- if (!need_byteswap) return ERROR_SUCCESS; /* nothing to do */
+ if (!need_byteswap && zeropad_mask == ~0u) return ERROR_SUCCESS; /* nothing to do */
}
src = src_bits->ptr;
dst = dst_bits->ptr;
+ padding_pos = width_bytes/sizeof(unsigned int) - 1;
if (info->bmiHeader.biHeight > 0)
{
@@ -1701,21 +1730,31 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
{
case 1:
for (y = 0; y < height; y++, src += image->bytes_per_line, dst += width_bytes)
+ {
for (x = 0; x < image->bytes_per_line; x++)
dst[x] = bit_swap[src[x]];
+ ((unsigned int *)dst)[padding_pos] &= zeropad_mask;
+ }
break;
case 4:
for (y = 0; y < height; y++, src += image->bytes_per_line, dst += width_bytes)
+ {
for (x = 0; x < image->bytes_per_line; x++)
dst[x] = (src[x] << 4) | (src[x] >> 4);
+ ((unsigned int *)dst)[padding_pos] &= zeropad_mask;
+ }
break;
case 16:
for (y = 0; y < height; y++, src += image->bytes_per_line, dst += width_bytes)
+ {
for (x = 0; x < info->bmiHeader.biWidth; x++)
((USHORT *)dst)[x] = RtlUshortByteSwap( ((const USHORT *)src)[x] );
+ ((unsigned int *)dst)[padding_pos] &= zeropad_mask;
+ }
break;
case 24:
for (y = 0; y < height; y++, src += image->bytes_per_line, dst += width_bytes)
+ {
for (x = 0; x < info->bmiHeader.biWidth; x++)
{
unsigned char tmp = src[3 * x];
@@ -1723,6 +1762,8 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
dst[3 * x + 1] = src[3 * x + 1];
dst[3 * x + 2] = tmp;
}
+ ((unsigned int *)dst)[padding_pos] &= zeropad_mask;
+ }
break;
case 32:
for (y = 0; y < height; y++, src += image->bytes_per_line, dst += width_bytes)
@@ -1731,10 +1772,18 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
break;
}
}
- else
+ else if (src != dst)
{
for (y = 0; y < height; y++, src += image->bytes_per_line, dst += width_bytes)
+ {
memcpy( dst, src, image->bytes_per_line );
+ ((unsigned int *)dst)[padding_pos] &= zeropad_mask;
+ }
+ }
+ else /* only need to clear the padding */
+ {
+ for (y = 0; y < height; y++, dst += width_bytes)
+ ((unsigned int *)dst)[padding_pos] &= zeropad_mask;
}
return ERROR_SUCCESS;
}
@@ -1813,7 +1862,7 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const str
wine_tsx11_unlock();
if (!image) return ERROR_OUTOFMEMORY;
- ret = copy_image_bits( info, color_shifts, image, bits, &dst_bits );
+ ret = copy_image_bits( info, color_shifts, image, bits, &dst_bits, ~0u );
if (!ret)
{
@@ -1984,7 +2033,8 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
src_bits.ptr = image->data;
src_bits.is_copy = TRUE;
- ret = copy_image_bits( info, color_shifts, image, &src_bits, bits );
+ ret = copy_image_bits( info, color_shifts, image, &src_bits, bits,
+ zeropad_masks[(width * image->bits_per_pixel) & 31] );
if (!ret && bits->ptr == image->data)
{
More information about the wine-cvs
mailing list