Alexandre Julliard : winex11: Split copy_image_bits into a couple of helper functions.
Alexandre Julliard
julliard at winehq.org
Wed Oct 3 13:20:35 CDT 2012
Module: wine
Branch: master
Commit: 219e2a35452e4405e666316943658823d6a63482
URL: http://source.winehq.org/git/wine.git/?a=commit;h=219e2a35452e4405e666316943658823d6a63482
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Oct 3 12:43:44 2012 +0200
winex11: Split copy_image_bits into a couple of helper functions.
---
dlls/winex11.drv/bitblt.c | 189 +++++++++++++++++++++++---------------------
1 files changed, 99 insertions(+), 90 deletions(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c
index 36e3ac9..2195fe5 100644
--- a/dlls/winex11.drv/bitblt.c
+++ b/dlls/winex11.drv/bitblt.c
@@ -1036,41 +1036,122 @@ static inline BOOL is_r8g8b8( const XVisualInfo *vis )
return vis->depth == 24 && vis->red_mask == 0xff0000 && vis->blue_mask == 0x0000ff;
}
-/* copy the image bits, fixing up alignment and byte swapping as necessary */
-DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
- const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits,
- struct bitblt_coords *coords, const int *mapping, unsigned int zeropad_mask )
+static inline BOOL image_needs_byteswap( XImage *image, BOOL is_r8g8b8, int bit_count )
{
#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 = coords->visrect.bottom - coords->visrect.top;
- int width_bytes = image->bytes_per_line;
- int padding_pos;
- unsigned char *src, *dst;
+
+ switch (bit_count)
+ {
+ case 1: return image->bitmap_bit_order != MSBFirst;
+ case 4: return image->byte_order != MSBFirst;
+ case 16:
+ case 32: return image->byte_order != client_byte_order;
+ case 24: return (image->byte_order == MSBFirst) ^ !is_r8g8b8;
+ default: return FALSE;
+ }
+}
+
+/* copy image bits with byte swapping and/or pixel mapping */
+static void copy_image_byteswap( BITMAPINFO *info, const unsigned char *src, unsigned char *dst,
+ int src_stride, int dst_stride, int height,
+ BOOL byteswap, const int *mapping, unsigned int zeropad_mask )
+{
+ int x, y, padding_pos = abs(dst_stride) / sizeof(unsigned int) - 1;
+
+ if (!byteswap && !mapping) /* simply copy */
+ {
+ if (src != dst)
+ {
+ for (y = 0; y < height; y++, src += src_stride, dst += dst_stride)
+ {
+ memcpy( dst, src, src_stride );
+ ((unsigned int *)dst)[padding_pos] &= zeropad_mask;
+ }
+ }
+ else if (zeropad_mask != ~0u) /* only need to clear the padding */
+ {
+ for (y = 0; y < height; y++, dst += dst_stride)
+ ((unsigned int *)dst)[padding_pos] &= zeropad_mask;
+ }
+ return;
+ }
switch (info->bmiHeader.biBitCount)
{
case 1:
- need_byteswap = (image->bitmap_bit_order != MSBFirst);
+ for (y = 0; y < height; y++, src += src_stride, dst += dst_stride)
+ {
+ for (x = 0; x < src_stride; x++) dst[x] = bit_swap[src[x]];
+ ((unsigned int *)dst)[padding_pos] &= zeropad_mask;
+ }
break;
case 4:
- need_byteswap = (image->byte_order != MSBFirst);
+ for (y = 0; y < height; y++, src += src_stride, dst += dst_stride)
+ {
+ if (mapping)
+ {
+ if (byteswap)
+ for (x = 0; x < src_stride; x++)
+ dst[x] = (mapping[src[x] & 0x0f] << 4) | mapping[src[x] >> 4];
+ else
+ for (x = 0; x < src_stride; x++)
+ dst[x] = mapping[src[x] & 0x0f] | (mapping[src[x] >> 4] << 4);
+ }
+ else
+ for (x = 0; x < src_stride; x++)
+ dst[x] = (src[x] << 4) | (src[x] >> 4);
+ ((unsigned int *)dst)[padding_pos] &= zeropad_mask;
+ }
+ break;
+ case 8:
+ for (y = 0; y < height; y++, src += src_stride, dst += dst_stride)
+ {
+ for (x = 0; x < src_stride; x++) dst[x] = mapping[src[x]];
+ ((unsigned int *)dst)[padding_pos] &= zeropad_mask;
+ }
break;
case 16:
- case 32:
- need_byteswap = (image->byte_order != client_byte_order);
+ for (y = 0; y < height; y++, src += src_stride, dst += dst_stride)
+ {
+ 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:
- need_byteswap = (image->byte_order == MSBFirst) ^ !is_r8g8b8;
+ for (y = 0; y < height; y++, src += src_stride, dst += dst_stride)
+ {
+ for (x = 0; x < info->bmiHeader.biWidth; x++)
+ {
+ unsigned char tmp = src[3 * x];
+ dst[3 * x] = src[3 * x + 2];
+ dst[3 * x + 1] = src[3 * x + 1];
+ dst[3 * x + 2] = tmp;
+ }
+ ((unsigned int *)dst)[padding_pos] &= zeropad_mask;
+ }
break;
- default:
- need_byteswap = FALSE;
+ case 32:
+ for (y = 0; y < height; y++, src += src_stride, dst += dst_stride)
+ for (x = 0; x < info->bmiHeader.biWidth; x++)
+ ((ULONG *)dst)[x] = RtlUlongByteSwap( ((const ULONG *)src)[x] );
break;
}
+}
+
+/* copy the image bits, fixing up alignment and byte swapping as necessary */
+DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
+ const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits,
+ struct bitblt_coords *coords, const int *mapping, unsigned int zeropad_mask )
+{
+ BOOL need_byteswap = image_needs_byteswap( image, is_r8g8b8, info->bmiHeader.biBitCount );
+ int height = coords->visrect.bottom - coords->visrect.top;
+ int width_bytes = image->bytes_per_line;
+ unsigned char *src, *dst;
src = src_bits->ptr;
if (info->bmiHeader.biHeight > 0)
@@ -1101,7 +1182,6 @@ DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
}
dst = dst_bits->ptr;
- padding_pos = width_bytes/sizeof(unsigned int) - 1;
if (info->bmiHeader.biHeight > 0)
{
@@ -1109,79 +1189,8 @@ DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
width_bytes = -width_bytes;
}
- if (need_byteswap || mapping)
- {
- switch (info->bmiHeader.biBitCount)
- {
- 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)
- {
- if (mapping)
- for (x = 0; x < image->bytes_per_line; x++)
- dst[x] = (mapping[src[x] & 0x0f] << 4) | mapping[src[x] >> 4];
- else
- 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 8:
- 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] = mapping[src[x]];
- ((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];
- dst[3 * x] = src[3 * x + 2];
- 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)
- for (x = 0; x < info->bmiHeader.biWidth; x++)
- ((ULONG *)dst)[x] = RtlUlongByteSwap( ((const ULONG *)src)[x] );
- break;
- }
- }
- 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;
- }
+ copy_image_byteswap( info, src, dst, image->bytes_per_line, width_bytes, height,
+ need_byteswap, mapping, zeropad_mask );
return ERROR_SUCCESS;
}
More information about the wine-cvs
mailing list