Alexandre Julliard : winex11: Remap pixels to system palette in Get/ PutImage for 4 and 8 bpp.
Alexandre Julliard
julliard at winehq.org
Wed Jul 20 12:54:40 CDT 2011
Module: wine
Branch: master
Commit: be74c47e867da6f767b911cc4678af00f9b00b55
URL: http://source.winehq.org/git/wine.git/?a=commit;h=be74c47e867da6f767b911cc4678af00f9b00b55
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Jul 18 14:48:01 2011 +0200
winex11: Remap pixels to system palette in Get/PutImage for 4 and 8 bpp.
---
dlls/winex11.drv/bitblt.c | 40 ++++++++++++++++++++++++++++++----------
1 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c
index 7a36b8b..836e251 100644
--- a/dlls/winex11.drv/bitblt.c
+++ b/dlls/winex11.drv/bitblt.c
@@ -1642,7 +1642,7 @@ 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,
- unsigned int zeropad_mask )
+ const int *mapping, unsigned int zeropad_mask )
{
#ifdef WORDS_BIGENDIAN
static const int client_byte_order = MSBFirst;
@@ -1678,6 +1678,7 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
if ((need_byteswap && !src_bits->is_copy) || /* need to swap bytes */
(zeropad_mask != ~0u && !src_bits->is_copy) || /* need to clear padding bytes */
+ (mapping && !src_bits->is_copy) || /* need to remap pixels */
(width_bytes & 3) || /* need to fixup line alignment */
(info->bmiHeader.biHeight > 0)) /* need to flip vertically */
{
@@ -1696,7 +1697,7 @@ 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 && zeropad_mask == ~0u) return ERROR_SUCCESS; /* nothing to do */
+ if (!need_byteswap && zeropad_mask == ~0u && !mapping) return ERROR_SUCCESS; /* nothing to do */
}
src = src_bits->ptr;
@@ -1709,7 +1710,7 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
width_bytes = -width_bytes;
}
- if (need_byteswap)
+ if (need_byteswap || mapping)
{
switch (info->bmiHeader.biBitCount)
{
@@ -1724,8 +1725,20 @@ static DWORD copy_image_bits( BITMAPINFO *info, const ColorShifts *color_shifts,
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] = (src[x] << 4) | (src[x] >> 4);
+ dst[x] = mapping[src[x]];
((unsigned int *)dst)[padding_pos] &= zeropad_mask;
}
break;
@@ -1787,6 +1800,8 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const str
struct gdi_image_bits dst_bits;
const XPixmapFormatValues *format;
const ColorShifts *color_shifts;
+ const BYTE *opcode = BITBLT_Opcodes[(rop >> 16) & 0xff];
+ const int *mapping = NULL;
if (hbitmap)
{
@@ -1845,7 +1860,13 @@ 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, ~0u );
+ if (image->bits_per_pixel == 4 || image->bits_per_pixel == 8)
+ {
+ if (bitmap || (!opcode[1] && OP_SRCDST(opcode[0]) == OP_ARGS(SRC,DST)))
+ mapping = X11DRV_PALETTE_PaletteToXPixel;
+ }
+
+ ret = copy_image_bits( info, color_shifts, image, bits, &dst_bits, mapping, ~0u );
if (!ret)
{
@@ -1862,8 +1883,6 @@ DWORD X11DRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info, const str
}
else
{
- const BYTE *opcode = BITBLT_Opcodes[(rop >> 16) & 0xff];
-
X11DRV_LockDIBSection( physdev, DIB_Status_GdiMod );
/* optimization for single-op ROPs */
@@ -1931,6 +1950,7 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
struct gdi_image_bits src_bits;
const XPixmapFormatValues *format;
const ColorShifts *color_shifts;
+ const int *mapping = NULL;
if (hbitmap)
{
@@ -1952,8 +1972,8 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
switch (format->bits_per_pixel)
{
case 1: align = 32; break;
- case 4: align = 8; break;
- case 8: align = 4; break;
+ case 4: align = 8; mapping = X11DRV_PALETTE_XPixelToPalette; break;
+ case 8: align = 4; mapping = X11DRV_PALETTE_XPixelToPalette; break;
case 16: align = 2; break;
case 24: align = 4; break;
case 32: align = 1; break;
@@ -2021,7 +2041,7 @@ 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, mapping,
zeropad_masks[(width * image->bits_per_pixel) & 31] );
if (!ret && bits->ptr == image->data)
More information about the wine-cvs
mailing list