From 8c3080f34539258f64c934b530a800b5c18fa1ca Mon Sep 17 00:00:00 2001 From: Pavel Tsekov Date: Tue, 29 Jul 2014 11:19:25 +0300 Subject: [PATCH 01/10] Fix 1bpp to 32bpp conversion with CLRCONV_ALPHA on * libfreerdp/codec/color.c (freerdp_mono_image_convert): Use ARGB32/ABGR32 when using 32bpp framebuffer and CLRCONV_ALPHA is set. --- libfreerdp/codec/color.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index 8b2578a8b..e7883036d 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -1092,11 +1092,25 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp { if ((bitMask >> bitIndex) & 0x01) { - *dst32 = (clrconv->invert) ? BGR32(redBg, greenBg, blueBg) : RGB32(redBg, greenBg, blueBg); + if (clrconv->alpha) + { + *dst32 = (clrconv->invert) ? ABGR32(0xFF, redBg, greenBg, blueBg) : ARGB32(0xFF, redBg, greenBg, blueBg); + } + else + { + *dst32 = (clrconv->invert) ? BGR32(redBg, greenBg, blueBg) : RGB32(redBg, greenBg, blueBg); + } } else { - *dst32 = (clrconv->invert) ? BGR32(redFg, greenFg, blueFg) : RGB32(redFg, greenFg, blueFg); + if (clrconv->alpha) + { + *dst32 = (clrconv->invert) ? ABGR32(0xFF, redFg, greenFg, blueFg) : ARGB32(0xFF, redFg, greenFg, blueFg); + } + else + { + *dst32 = (clrconv->invert) ? BGR32(redFg, greenFg, blueFg) : RGB32(redFg, greenFg, blueFg); + } } dst32++; } From e13f93aa1bc8e0e5f124e9856d7ce6c5345a42a7 Mon Sep 17 00:00:00 2001 From: Pavel Tsekov Date: Mon, 4 Aug 2014 18:14:08 +0300 Subject: [PATCH 02/10] Allow the user to enable/disable performance features regardless of their default values. --- .../Android/FreeRDPCore/jni/android_freerdp.c | 43 +++---------------- 1 file changed, 7 insertions(+), 36 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index 5f75ce40e..87b4d7f5f 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -836,44 +836,15 @@ JNIEXPORT void JNICALL jni_freerdp_set_performance_flags( } /* store performance settings */ - if (disableWallpaper == JNI_TRUE) - settings->DisableWallpaper = TRUE; - - if (disableFullWindowDrag == JNI_TRUE) - settings->DisableFullWindowDrag = TRUE; - - if (disableMenuAnimations == JNI_TRUE) - settings->DisableMenuAnims = TRUE; - - if (disableTheming == JNI_TRUE) - settings->DisableThemes = TRUE; - - if (enableFontSmoothing == JNI_TRUE) - settings->AllowFontSmoothing = TRUE; - - if(enableDesktopComposition == JNI_TRUE) - settings->AllowDesktopComposition = TRUE; - + settings->DisableWallpaper = (disableWallpaper == JNI_TRUE) ? TRUE : FALSE; + settings->DisableFullWindowDrag = (disableFullWindowDrag == JNI_TRUE) ? TRUE : FALSE; + settings->DisableMenuAnims = (disableMenuAnimations == JNI_TRUE) ? TRUE : FALSE; + settings->DisableThemes = (disableTheming == JNI_TRUE) ? TRUE : FALSE; + settings->AllowFontSmoothing = (enableFontSmoothing == JNI_TRUE) ? TRUE : FALSE; + settings->AllowDesktopComposition = (enableDesktopComposition == JNI_TRUE) ? TRUE : FALSE; /* Create performance flags from settings */ - settings->PerformanceFlags = PERF_FLAG_NONE; - if (settings->AllowFontSmoothing) - settings->PerformanceFlags |= PERF_ENABLE_FONT_SMOOTHING; - - if (settings->AllowDesktopComposition) - settings->PerformanceFlags |= PERF_ENABLE_DESKTOP_COMPOSITION; - - if (settings->DisableWallpaper) - settings->PerformanceFlags |= PERF_DISABLE_WALLPAPER; - - if (settings->DisableFullWindowDrag) - settings->PerformanceFlags |= PERF_DISABLE_FULLWINDOWDRAG; - - if (settings->DisableMenuAnims) - settings->PerformanceFlags |= PERF_DISABLE_MENUANIMATIONS; - - if (settings->DisableThemes) - settings->PerformanceFlags |= PERF_DISABLE_THEMING; + freerdp_performance_flags_make(settings); DEBUG_ANDROID("performance_flags: %04X", settings->PerformanceFlags); } From 8a4f134fab1989c222caacb32fd0702ce2059ec3 Mon Sep 17 00:00:00 2001 From: "U-PAVEL\\Pavel Tsekov" Date: Tue, 5 Aug 2014 14:35:31 +0300 Subject: [PATCH 03/10] Revert to 15d2b35574d7eac8d465029854cc3c4bd64ae2cc --- .../Android/FreeRDPCore/jni/android_freerdp.c | 43 ++++++++++++++++--- libfreerdp/codec/color.c | 18 +------- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index 87b4d7f5f..5f75ce40e 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -836,15 +836,44 @@ JNIEXPORT void JNICALL jni_freerdp_set_performance_flags( } /* store performance settings */ - settings->DisableWallpaper = (disableWallpaper == JNI_TRUE) ? TRUE : FALSE; - settings->DisableFullWindowDrag = (disableFullWindowDrag == JNI_TRUE) ? TRUE : FALSE; - settings->DisableMenuAnims = (disableMenuAnimations == JNI_TRUE) ? TRUE : FALSE; - settings->DisableThemes = (disableTheming == JNI_TRUE) ? TRUE : FALSE; - settings->AllowFontSmoothing = (enableFontSmoothing == JNI_TRUE) ? TRUE : FALSE; - settings->AllowDesktopComposition = (enableDesktopComposition == JNI_TRUE) ? TRUE : FALSE; + if (disableWallpaper == JNI_TRUE) + settings->DisableWallpaper = TRUE; + + if (disableFullWindowDrag == JNI_TRUE) + settings->DisableFullWindowDrag = TRUE; + + if (disableMenuAnimations == JNI_TRUE) + settings->DisableMenuAnims = TRUE; + + if (disableTheming == JNI_TRUE) + settings->DisableThemes = TRUE; + + if (enableFontSmoothing == JNI_TRUE) + settings->AllowFontSmoothing = TRUE; + + if(enableDesktopComposition == JNI_TRUE) + settings->AllowDesktopComposition = TRUE; + /* Create performance flags from settings */ - freerdp_performance_flags_make(settings); + settings->PerformanceFlags = PERF_FLAG_NONE; + if (settings->AllowFontSmoothing) + settings->PerformanceFlags |= PERF_ENABLE_FONT_SMOOTHING; + + if (settings->AllowDesktopComposition) + settings->PerformanceFlags |= PERF_ENABLE_DESKTOP_COMPOSITION; + + if (settings->DisableWallpaper) + settings->PerformanceFlags |= PERF_DISABLE_WALLPAPER; + + if (settings->DisableFullWindowDrag) + settings->PerformanceFlags |= PERF_DISABLE_FULLWINDOWDRAG; + + if (settings->DisableMenuAnims) + settings->PerformanceFlags |= PERF_DISABLE_MENUANIMATIONS; + + if (settings->DisableThemes) + settings->PerformanceFlags |= PERF_DISABLE_THEMING; DEBUG_ANDROID("performance_flags: %04X", settings->PerformanceFlags); } diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index e7883036d..8b2578a8b 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -1092,25 +1092,11 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp { if ((bitMask >> bitIndex) & 0x01) { - if (clrconv->alpha) - { - *dst32 = (clrconv->invert) ? ABGR32(0xFF, redBg, greenBg, blueBg) : ARGB32(0xFF, redBg, greenBg, blueBg); - } - else - { - *dst32 = (clrconv->invert) ? BGR32(redBg, greenBg, blueBg) : RGB32(redBg, greenBg, blueBg); - } + *dst32 = (clrconv->invert) ? BGR32(redBg, greenBg, blueBg) : RGB32(redBg, greenBg, blueBg); } else { - if (clrconv->alpha) - { - *dst32 = (clrconv->invert) ? ABGR32(0xFF, redFg, greenFg, blueFg) : ARGB32(0xFF, redFg, greenFg, blueFg); - } - else - { - *dst32 = (clrconv->invert) ? BGR32(redFg, greenFg, blueFg) : RGB32(redFg, greenFg, blueFg); - } + *dst32 = (clrconv->invert) ? BGR32(redFg, greenFg, blueFg) : RGB32(redFg, greenFg, blueFg); } dst32++; } From c51c5df2ff7e7cd79464155fbb9189a17fa03852 Mon Sep 17 00:00:00 2001 From: Pavel Tsekov Date: Thu, 7 Aug 2014 00:58:58 +0300 Subject: [PATCH 04/10] * include/freerdp/codec/color.h: (freerdp_color_convert_drawing_order_color_to_gdi_color): Declare new function. * libfreerdp/codec/color.c: (freerdp_color_convert_drawing_order_color_to_gdi_color): Implement. (freerdp_image_convert_8bpp): Properly use the ARGB32/ABGR32/RGB32/BGR32 macros when converting 8bpp data to 32bpp. (freerdp_image_convert_32bpp): Fix CLRCONV_ALPHA and CLRCONV_INVERT processing for 32bpp destination. (freerdp_mono_image_convert): Use ARGB32/ABGR32 when converting to 32bpp and CLRCONV_ALPHA is set. * libfreerdp/core/orders.c: Color data from drawing orders is interpreted in big endian mode. * libfreerdp/core/update.c (update_read_palette): Likewise. * libfreerdp/gdi/16bpp.c (gdi_get_color_16bpp): GDI colors are stored as RGB now. * libfreerdp/gdi/32bpp.c (gdi_get_color_32bpp): Likewise. * libfreerdp/gdi/gdi.c: Use freerdp_color_convert_drawing_order_color_to_gdi_color() to convert from drawing order color representation to GDI color representation troughout. * libfreerdp/gdi/graphics.c (gdi_Glyph_BeginDraw): Likewise. (gdi_Glyph_EndDraw): Likewise. --- include/freerdp/codec/color.h | 1 + libfreerdp/codec/color.c | 136 ++++++++++++++++++++++------------ libfreerdp/core/orders.c | 18 ++--- libfreerdp/core/update.c | 4 +- libfreerdp/gdi/16bpp.c | 2 +- libfreerdp/gdi/32bpp.c | 2 +- libfreerdp/gdi/gdi.c | 24 +++--- libfreerdp/gdi/graphics.c | 9 ++- 8 files changed, 121 insertions(+), 75 deletions(-) diff --git a/include/freerdp/codec/color.h b/include/freerdp/codec/color.h index 4fdaf8aa9..c0c6f1b67 100644 --- a/include/freerdp/codec/color.h +++ b/include/freerdp/codec/color.h @@ -392,6 +392,7 @@ FREERDP_API UINT32 freerdp_color_convert_rgb_bgr(UINT32 srcColor, int srcBpp, in FREERDP_API UINT32 freerdp_color_convert_bgr_rgb(UINT32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); FREERDP_API UINT32 freerdp_color_convert_var_rgb(UINT32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); FREERDP_API UINT32 freerdp_color_convert_var_bgr(UINT32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); +FREERDP_API UINT32 freerdp_color_convert_drawing_order_color_to_gdi_color(UINT32 color, int bpp, HCLRCONV clrconv); FREERDP_API HCLRCONV freerdp_clrconv_new(UINT32 flags); FREERDP_API void freerdp_clrconv_free(HCLRCONV clrconv); diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index 8b2578a8b..305801de7 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -379,6 +379,43 @@ UINT32 freerdp_color_convert_var_bgr(UINT32 srcColor, int srcBpp, int dstBpp, HC return freerdp_color_convert_rgb_bgr(srcColor, srcBpp, dstBpp, clrconv); } +UINT32 freerdp_color_convert_drawing_order_color_to_gdi_color(UINT32 color, int bpp, HCLRCONV clrconv) +{ + UINT32 r, g, b; + + switch (bpp) + { + case 16: + color = (color & (UINT32) 0xFF00) | ((color >> 16) & (UINT32) 0xFF); + GetRGB16(r, g, b, color); + break; + + case 15: + color = (color & (UINT32) 0xFF00) | ((color >> 16) & (UINT32) 0xFF); + GetRGB15(r, g, b, color); + break; + + case 8: + color = (color >> 16) & (UINT32) 0xFF; + r = clrconv->palette->entries[color].red; + g = clrconv->palette->entries[color].green; + b = clrconv->palette->entries[color].blue; + break; + + case 1: + r = g = b = 0; + if (color != 0) + r = g = b = 0xFF; + break; + + default: + return color; + break; + } + + return RGB32(r, g, b); +} + BYTE* freerdp_image_convert_8bpp(BYTE* srcData, BYTE* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv) { int i; @@ -470,11 +507,11 @@ BYTE* freerdp_image_convert_8bpp(BYTE* srcData, BYTE* dstData, int width, int he blue = clrconv->palette->entries[pixel].blue; if (clrconv->alpha) { - pixel = (clrconv->invert) ? ARGB32(0xFF, red, green, blue) : ABGR32(0xFF, red, green, blue); + pixel = (clrconv->invert) ? ABGR32(0xFF, red, green, blue) : ARGB32(0xFF, red, green, blue); } else { - pixel = (clrconv->invert) ? RGB32(red, green, blue) : BGR32(red, green, blue); + pixel = (clrconv->invert) ? BGR32(red, green, blue) : RGB32(red, green, blue); } *dst32 = pixel; dst32++; @@ -760,33 +797,47 @@ BYTE* freerdp_image_convert_32bpp(BYTE* srcData, BYTE* dstData, int width, int h } else if (dstBpp == 32) { + int i; + UINT32 pixel; + UINT32 alpha_mask; + UINT32* srcp; + UINT32* dstp; + BYTE red, green, blue; + if (!dstData) dstData = (BYTE*) _aligned_malloc(width * height * 4, 16); if (!dstData) return NULL; - if (clrconv->alpha) + alpha_mask = clrconv->alpha ? 0xFF000000 : 0; + + srcp = (UINT32*) srcData; + dstp = (UINT32*) dstData; + + if (clrconv->invert) { - int x, y; - BYTE* dstp; - - CopyMemory(dstData, srcData, width * height * 4); - - dstp = dstData; - for (y = 0; y < height; y++) + for (i = width * height; i > 0; i--) { - for (x = 0; x < width * 4; x += 4) - { - dstp += 3; - *dstp = 0xFF; - dstp++; - } + pixel = *srcp; + srcp++; + GetRGB32(red, green, blue, pixel); + pixel = alpha_mask | BGR32(red, green, blue); + *dstp = pixel; + dstp++; } } else { - CopyMemory(dstData, srcData, width * height * 4); + for (i = width * height; i > 0; i--) + { + pixel = *srcp; + srcp++; + GetRGB32(red, green, blue, pixel); + pixel = alpha_mask | RGB32(red, green, blue); + *dstp = pixel; + dstp++; + } } return dstData; @@ -995,36 +1046,9 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp int bitIndex; BYTE redBg, greenBg, blueBg; BYTE redFg, greenFg, blueFg; - - switch (srcBpp) - { - case 8: - bgcolor &= 0xFF; - redBg = clrconv->palette->entries[bgcolor].red; - greenBg = clrconv->palette->entries[bgcolor].green; - blueBg = clrconv->palette->entries[bgcolor].blue; - - fgcolor &= 0xFF; - redFg = clrconv->palette->entries[fgcolor].red; - greenFg = clrconv->palette->entries[fgcolor].green; - blueFg = clrconv->palette->entries[fgcolor].blue; - break; - - case 16: - GetRGB16(redBg, greenBg, blueBg, bgcolor); - GetRGB16(redFg, greenFg, blueFg, fgcolor); - break; - - case 15: - GetRGB15(redBg, greenBg, blueBg, bgcolor); - GetRGB15(redFg, greenFg, blueFg, fgcolor); - break; - - default: - GetRGB32(redBg, greenBg, blueBg, bgcolor); - GetRGB32(redFg, greenFg, blueFg, fgcolor); - break; - } + + GetRGB32(redBg, greenBg, blueBg, bgcolor); + GetRGB32(redFg, greenFg, blueFg, fgcolor); if (dstBpp == 16) { @@ -1092,11 +1116,25 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp { if ((bitMask >> bitIndex) & 0x01) { - *dst32 = (clrconv->invert) ? BGR32(redBg, greenBg, blueBg) : RGB32(redBg, greenBg, blueBg); + if (clrconv->alpha) + { + *dst32 = (clrconv->invert) ? ABGR32(0xFF, redBg, greenBg, blueBg) : ARGB32(0xFF, redBg, greenBg, blueBg); + } + else + { + *dst32 = (clrconv->invert) ? BGR32(redBg, greenBg, blueBg) : RGB32(redBg, greenBg, blueBg); + } } else { - *dst32 = (clrconv->invert) ? BGR32(redFg, greenFg, blueFg) : RGB32(redFg, greenFg, blueFg); + if (clrconv->alpha) + { + *dst32 = (clrconv->invert) ? ABGR32(0xFF, redFg, greenFg, blueFg) : ARGB32(0xFF, redFg, greenFg, blueFg); + } + else + { + *dst32 = (clrconv->invert) ? BGR32(redFg, greenFg, blueFg) : RGB32(redFg, greenFg, blueFg); + } } dst32++; } diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index 98b177f67..b5f7461c4 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -223,11 +223,11 @@ static INLINE BOOL update_read_color(wStream* s, UINT32* color) return FALSE; Stream_Read_UINT8(s, byte); - *color = byte; + *color = (UINT32) byte << 16; Stream_Read_UINT8(s, byte); - *color |= (byte << 8); + *color |= ((UINT32) byte << 8); Stream_Read_UINT8(s, byte); - *color |= (byte << 16); + *color |= (UINT32) byte; return TRUE; } @@ -979,7 +979,7 @@ BOOL update_read_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_REC return FALSE; Stream_Read_UINT8(s, byte); - opaque_rect->color = (opaque_rect->color & 0xFFFFFF00) | byte; + opaque_rect->color = (opaque_rect->color & 0xFF00FFFF) | ((UINT32) byte << 16); } if (orderInfo->fieldFlags & ORDER_FIELD_06) @@ -988,7 +988,7 @@ BOOL update_read_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_REC return FALSE; Stream_Read_UINT8(s, byte); - opaque_rect->color = (opaque_rect->color & 0xFFFF00FF) | (byte << 8); + opaque_rect->color = (opaque_rect->color & 0xFFFF00FF) | ((UINT32) byte << 8); } if (orderInfo->fieldFlags & ORDER_FIELD_07) @@ -997,7 +997,7 @@ BOOL update_read_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_REC return FALSE; Stream_Read_UINT8(s, byte); - opaque_rect->color = (opaque_rect->color & 0xFF00FFFF) | (byte << 16); + opaque_rect->color = (opaque_rect->color & 0xFFFFFF00) | (UINT32) byte; } return TRUE; @@ -1178,7 +1178,7 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT return FALSE; Stream_Read_UINT8(s, byte); - multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFFFF00) | byte; + multi_opaque_rect->color = (multi_opaque_rect->color & 0xFF00FFFF) | ((UINT32) byte << 16); } if (orderInfo->fieldFlags & ORDER_FIELD_06) @@ -1187,7 +1187,7 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT return FALSE; Stream_Read_UINT8(s, byte); - multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFF00FF) | (byte << 8); + multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFF00FF) | ((UINT32) byte << 8); } if (orderInfo->fieldFlags & ORDER_FIELD_07) @@ -1196,7 +1196,7 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT return FALSE; Stream_Read_UINT8(s, byte); - multi_opaque_rect->color = (multi_opaque_rect->color & 0xFF00FFFF) | (byte << 16); + multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFFFF00) | (UINT32) byte; } ORDER_FIELD_BYTE(8, multi_opaque_rect->numRectangles); diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 9f8343d56..7b3897d46 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -230,9 +230,9 @@ BOOL update_read_palette(rdpUpdate* update, wStream* s, PALETTE_UPDATE* palette_ { entry = &palette_update->entries[i]; - Stream_Read_UINT8(s, entry->blue); - Stream_Read_UINT8(s, entry->green); Stream_Read_UINT8(s, entry->red); + Stream_Read_UINT8(s, entry->green); + Stream_Read_UINT8(s, entry->blue); } return TRUE; } diff --git a/libfreerdp/gdi/16bpp.c b/libfreerdp/gdi/16bpp.c index 3f96425e6..c595976fe 100644 --- a/libfreerdp/gdi/16bpp.c +++ b/libfreerdp/gdi/16bpp.c @@ -43,7 +43,7 @@ UINT16 gdi_get_color_16bpp(HGDI_DC hdc, GDI_COLOR color) BYTE r, g, b; UINT16 color16; - GetBGR32(r, g, b, color); + GetRGB32(r, g, b, color); if (hdc->rgb555) { diff --git a/libfreerdp/gdi/32bpp.c b/libfreerdp/gdi/32bpp.c index 33e1d19d9..c9df0f16a 100644 --- a/libfreerdp/gdi/32bpp.c +++ b/libfreerdp/gdi/32bpp.c @@ -44,7 +44,7 @@ UINT32 gdi_get_color_32bpp(HGDI_DC hdc, GDI_COLOR color) BYTE a, r, g, b; a = 0xFF; - GetBGR32(r, g, b, color); + GetRGB32(r, g, b, color); if (hdc->invert) { diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 86fbb7e7b..e40656417 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -495,8 +495,8 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) brush = &patblt->brush; - foreColor = freerdp_color_convert_rgb(patblt->foreColor, gdi->srcBpp, 24, gdi->clrconv); - backColor = freerdp_color_convert_rgb(patblt->backColor, gdi->srcBpp, 24, gdi->clrconv); + foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(patblt->foreColor, gdi->srcBpp, gdi->clrconv); + backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(patblt->backColor, gdi->srcBpp, gdi->clrconv); originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor); @@ -541,7 +541,7 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) else { data = freerdp_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp, - patblt->backColor, patblt->foreColor, gdi->clrconv); + backColor, foreColor, gdi->clrconv); } hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data); @@ -582,7 +582,8 @@ void gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) gdi_CRgnToRect(opaque_rect->nLeftRect, opaque_rect->nTopRect, opaque_rect->nWidth, opaque_rect->nHeight, &rect); - brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, gdi->srcBpp, 32, gdi->clrconv); + brush_color = freerdp_color_convert_drawing_order_color_to_gdi_color( + opaque_rect->color, gdi->srcBpp, gdi->clrconv); hBrush = gdi_CreateSolidBrush(brush_color); gdi_FillRect(gdi->drawing->hdc, &rect, hBrush); @@ -606,7 +607,8 @@ void gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_o gdi_CRgnToRect(rectangle->left, rectangle->top, rectangle->width, rectangle->height, &rect); - brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, gdi->srcBpp, 32, gdi->clrconv); + brush_color = freerdp_color_convert_drawing_order_color_to_gdi_color( + multi_opaque_rect->color, gdi->srcBpp, gdi->clrconv); hBrush = gdi_CreateSolidBrush(brush_color); gdi_FillRect(gdi->drawing->hdc, &rect, hBrush); @@ -621,7 +623,8 @@ void gdi_line_to(rdpContext* context, LINE_TO_ORDER* lineTo) HGDI_PEN hPen; rdpGdi* gdi = context->gdi; - color = freerdp_color_convert_rgb(lineTo->penColor, gdi->srcBpp, 32, gdi->clrconv); + color = freerdp_color_convert_drawing_order_color_to_gdi_color( + lineTo->penColor, gdi->srcBpp, gdi->clrconv); hPen = gdi_CreatePen(lineTo->penStyle, lineTo->penWidth, (GDI_COLOR) color); gdi_SelectObject(gdi->drawing->hdc, (HGDIOBJECT) hPen); gdi_SetROP2(gdi->drawing->hdc, lineTo->bRop2); @@ -642,7 +645,8 @@ void gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) DELTA_POINT* points; rdpGdi* gdi = context->gdi; - color = freerdp_color_convert_rgb(polyline->penColor, gdi->srcBpp, 32, gdi->clrconv); + color = freerdp_color_convert_drawing_order_color_to_gdi_color( + polyline->penColor, gdi->srcBpp, gdi->clrconv); hPen = gdi_CreatePen(GDI_PS_SOLID, 1, (GDI_COLOR) color); gdi_SelectObject(gdi->drawing->hdc, (HGDIOBJECT) hPen); gdi_SetROP2(gdi->drawing->hdc, polyline->bRop2); @@ -689,8 +693,8 @@ void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) brush = &mem3blt->brush; bitmap = (gdiBitmap*) mem3blt->bitmap; - foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, gdi->srcBpp, 24, gdi->clrconv); - backColor = freerdp_color_convert_rgb(mem3blt->backColor, gdi->srcBpp, 24, gdi->clrconv); + foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(mem3blt->foreColor, gdi->srcBpp, gdi->clrconv); + backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(mem3blt->backColor, gdi->srcBpp, gdi->clrconv); originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor); @@ -717,7 +721,7 @@ void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) else { data = freerdp_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp, - mem3blt->backColor, mem3blt->foreColor, gdi->clrconv); + backColor, foreColor, gdi->clrconv); } hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data); diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c index 9f502fae8..2a546abd6 100644 --- a/libfreerdp/gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -242,8 +242,10 @@ void gdi_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int heigh HGDI_BRUSH brush; rdpGdi* gdi = context->gdi; - bgcolor = freerdp_color_convert_var_bgr(bgcolor, gdi->srcBpp, 32, gdi->clrconv); - fgcolor = freerdp_color_convert_var_bgr(fgcolor, gdi->srcBpp, 32, gdi->clrconv); + bgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color( + bgcolor, gdi->srcBpp, gdi->clrconv); + fgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color( + fgcolor, gdi->srcBpp, gdi->clrconv); gdi_CRgnToRect(x, y, width, height, &rect); @@ -258,7 +260,8 @@ void gdi_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, { rdpGdi* gdi = context->gdi; - bgcolor = freerdp_color_convert_var_bgr(bgcolor, gdi->srcBpp, 32, gdi->clrconv); + bgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color( + bgcolor, gdi->srcBpp, gdi->clrconv); gdi->textColor = gdi_SetTextColor(gdi->drawing->hdc, bgcolor); } From 98cf129a11ade4c05abb31c5faa1f5e4bb8aea6b Mon Sep 17 00:00:00 2001 From: Pavel Tsekov Date: Thu, 7 Aug 2014 01:12:39 +0300 Subject: [PATCH 05/10] Do not invert fb contents when in 32bpp mode * client/Android/FreeRDPCore/jni/android_freerdp.c: (android_post_connect): Pass the proper flags to gdi_init(). (copy_pixel_buffer): Do not invert the framebuffer data when using 32bpp framebuffer. --- .../Android/FreeRDPCore/jni/android_freerdp.c | 40 ++++++------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index 5f75ce40e..544771902 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -141,6 +141,7 @@ BOOL android_pre_connect(freerdp* instance) static BOOL android_post_connect(freerdp* instance) { + UINT32 gdi_flags; rdpSettings *settings = instance->settings; DEBUG_ANDROID("android_post_connect"); @@ -154,9 +155,12 @@ static BOOL android_post_connect(freerdp* instance) instance->context->cache = cache_new(settings); - gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | - ((instance->settings->ColorDepth > 16) ? CLRBUF_32BPP : CLRBUF_16BPP), - NULL); + if (instance->settings->ColorDepth > 16) + gdi_flags = CLRBUF_32BPP | CLRCONV_ALPHA | CLRCONV_INVERT; + else + gdi_flags = CLRBUF_16BPP; + + gdi_init(instance, gdi_flags, NULL); instance->update->BeginPaint = android_begin_paint; instance->update->EndPaint = android_end_paint; @@ -1014,7 +1018,7 @@ JNIEXPORT void JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jin static void copy_pixel_buffer(UINT8* dstBuf, UINT8* srcBuf, int x, int y, int width, int height, int wBuf, int hBuf, int bpp) { - int i, j; + int i; int length; int scanline; UINT8 *dstp, *srcp; @@ -1025,31 +1029,11 @@ static void copy_pixel_buffer(UINT8* dstBuf, UINT8* srcBuf, int x, int y, int wi srcp = (UINT8*) &srcBuf[(scanline * y) + (x * bpp)]; dstp = (UINT8*) &dstBuf[(scanline * y) + (x * bpp)]; - if (bpp == 4) + for (i = 0; i < height; i++) { - for (i = 0; i < height; i++) - { - for (j = 0; j < width * 4; j += 4) - { - // ARGB <-> ABGR - dstp[j + 0] = srcp[j + 2]; - dstp[j + 1] = srcp[j + 1]; - dstp[j + 2] = srcp[j + 0]; - dstp[j + 3] = srcp[j + 3]; - } - - srcp += scanline; - dstp += scanline; - } - } - else - { - for (i = 0; i < height; i++) - { - memcpy(dstp, srcp, length); - srcp += scanline; - dstp += scanline; - } + memcpy(dstp, srcp, length); + srcp += scanline; + dstp += scanline; } } From adb750f7ca43671885c41e64609ccb21b8ab8ca0 Mon Sep 17 00:00:00 2001 From: Pavel Tsekov Date: Thu, 7 Aug 2014 20:33:30 +0300 Subject: [PATCH 06/10] Convert NSCodec compressed bitmaps to framebuffer format. * libfreerdp/gdi/gdi.c (gdi_surface_bits): Convert NSCodec compressed bitmaps to framebuffer format. --- libfreerdp/gdi/gdi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index e40656417..f7cd4771d 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -855,7 +855,10 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co gdi->image->bitmap->bitsPerPixel = surface_bits_command->bpp; gdi->image->bitmap->bytesPerPixel = gdi->image->bitmap->bitsPerPixel / 8; gdi->image->bitmap->data = (BYTE*) _aligned_realloc(gdi->image->bitmap->data, gdi->image->bitmap->width * gdi->image->bitmap->height * 4, 16); - freerdp_image_flip(nsc_context->BitmapData, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, 32); + freerdp_image_convert(nsc_context->BitmapData, gdi->image->bitmap->data, + surface_bits_command->width, surface_bits_command->height, + surface_bits_command->bpp, gdi->dstBpp, gdi->clrconv); + freerdp_image_flip(gdi->image->bitmap->data, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, 32); gdi_BitBlt(gdi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY); } else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE) From 052173de5fcb9fa1845dc43a8db3c047ca9abff9 Mon Sep 17 00:00:00 2001 From: Pavel Tsekov Date: Thu, 7 Aug 2014 20:37:06 +0300 Subject: [PATCH 07/10] Do not assume 32bpp framebuffer when flipping NSCodec bitmaps. * libfreerdp/gdi/gdi.c (gdi_surface_bits): Do not assume 32bpp framebuffer when flipping NSCodec compressed bitmaps. --- libfreerdp/gdi/gdi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index f7cd4771d..e76012f0c 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -858,7 +858,7 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co freerdp_image_convert(nsc_context->BitmapData, gdi->image->bitmap->data, surface_bits_command->width, surface_bits_command->height, surface_bits_command->bpp, gdi->dstBpp, gdi->clrconv); - freerdp_image_flip(gdi->image->bitmap->data, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, 32); + freerdp_image_flip(gdi->image->bitmap->data, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, gdi->dstBpp); gdi_BitBlt(gdi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY); } else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE) From 53e19e0da7ecea476241abc4f25318d4f69e1e11 Mon Sep 17 00:00:00 2001 From: Pavel Tsekov Date: Thu, 14 Aug 2014 00:31:15 +0300 Subject: [PATCH 08/10] Fix conversion of 24bpp bitmaps to 32bpp fb when CLRCONV_INVERT and/or CLRCONV_ALPHA is set. * include/freerdp/codec/color.h (RGB32_to_BGR32): New inline function. * libfreerdp/codec/color.c: (freerdp_image_convert_24bpp): Fix CLRCONV_ALPHA and CLRCONV_INVERT processing for 32bpp destination. Unroll the conversion loop to process four pixels in one go using 32-bit load and store operations. --- include/freerdp/codec/color.h | 8 ++++ libfreerdp/codec/color.c | 83 ++++++++++++++++++++++++++++++++--- 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/include/freerdp/codec/color.h b/include/freerdp/codec/color.h index c0c6f1b67..47c6126e3 100644 --- a/include/freerdp/codec/color.h +++ b/include/freerdp/codec/color.h @@ -373,6 +373,14 @@ typedef CLRCONV* HCLRCONV; typedef BYTE* (*p_freerdp_image_convert)(BYTE* srcData, BYTE* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv); +static INLINE UINT32 RGB32_to_BGR32(UINT32 pixel) +{ + UINT32 temp; + + temp = (pixel ^ (pixel >> 16)) & ((1 << 8) - 1); + return (pixel ^ (temp | (temp << 16))); +} + FREERDP_API int freerdp_get_pixel(BYTE* data, int x, int y, int width, int height, int bpp); FREERDP_API void freerdp_set_pixel(BYTE* data, int x, int y, int width, int height, int bpp, int pixel); diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index 305801de7..365bdde46 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -705,7 +705,9 @@ BYTE* freerdp_image_convert_24bpp(BYTE* srcData, BYTE* dstData, int width, int h if (dstBpp == 32) { - BYTE* dstp; + UINT32 pixel, alpha_mask, temp; + UINT32* srcp; + UINT32* dstp; if (!dstData) dstData = (BYTE*) _aligned_malloc(width * height * 4, 16); @@ -713,14 +715,81 @@ BYTE* freerdp_image_convert_24bpp(BYTE* srcData, BYTE* dstData, int width, int h if (!dstData) return NULL; - dstp = dstData; + alpha_mask = clrconv->alpha ? 0xFF000000 : 0; - for (i = width * height; i > 0; i--) + srcp = (UINT32*) srcData; + dstp = (UINT32*) dstData; + + if (clrconv->invert) { - *(dstp++) = *(srcData++); - *(dstp++) = *(srcData++); - *(dstp++) = *(srcData++); - *(dstp++) = 0xFF; + /* Each iteration handles four pixels using 32-bit load and + store operations. */ + for (i = ((width * height) / 4); i > 0; i--) + { + temp = 0; + + pixel = temp; + temp = *srcp++; + pixel |= temp & 0x00FFFFFF; + temp = temp >> 24; + *dstp++ = alpha_mask | RGB32_to_BGR32(pixel); + + pixel = temp; + temp = *srcp++; + pixel |= (temp & 0x0000FFFF) << 8; + temp = temp >> 16; + *dstp++ = alpha_mask | RGB32_to_BGR32(pixel); + + pixel = temp; + temp = *srcp++; + pixel |= (temp & 0x000000FF) << 16; + temp = temp >> 8; + *dstp++ = alpha_mask | RGB32_to_BGR32(pixel); + + *dstp++ = alpha_mask | RGB32_to_BGR32(temp); + } + + /* Handle any remainder. */ + for (i = (width * height) % 4; i > 0; i--) + { + pixel = ABGR32(alpha_mask, srcData[2], srcData[1], srcData[0]); + *dstp++ = pixel; + srcData += 3; + } + } + else + { + for (i = ((width * height) / 4); i > 0; i--) + { + temp = 0; + + pixel = temp; + temp = *srcp++; + pixel |= temp & 0x00FFFFFF; + temp = temp >> 24; + *dstp++ = alpha_mask | pixel; + + pixel = temp; + temp = *srcp++; + pixel |= (temp & 0x0000FFFF) << 8; + temp = temp >> 16; + *dstp++ = alpha_mask | pixel; + + pixel = temp; + temp = *srcp++; + pixel |= (temp & 0x000000FF) << 16; + temp = temp >> 8; + *dstp++ = alpha_mask | pixel; + + *dstp++ = alpha_mask | temp; + } + + for (i = (width * height) % 4; i > 0; i--) + { + pixel = ARGB32(alpha_mask, srcData[2], srcData[1], srcData[0]); + *dstp++ = pixel; + srcData += 3; + } } return dstData; From eab69c29840331f0a73d40bf4add635743db8bf5 Mon Sep 17 00:00:00 2001 From: Pavel Tsekov Date: Thu, 14 Aug 2014 20:09:12 +0300 Subject: [PATCH 09/10] Fix 1bpp -> 16bpp image conversion. * libfreerdp/codec/color.c (freerdp_mono_image_convert): Update the 1bpp -> 16bpp conversion code to reflect the fact that the foreground and the background colors are in GDI representation now. --- libfreerdp/codec/color.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index 365bdde46..2c1c8c2d8 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -1121,25 +1121,6 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp if (dstBpp == 16) { - if (clrconv->rgb555) - { - if (srcBpp == 16) - { - /* convert 15-bit colors to 16-bit colors */ - RGB16_RGB15(redBg, greenBg, blueBg, bgcolor); - RGB16_RGB15(redFg, greenFg, blueFg, fgcolor); - } - } - else - { - if (srcBpp == 15) - { - /* convert 15-bit colors to 16-bit colors */ - RGB15_RGB16(redBg, greenBg, blueBg, bgcolor); - RGB15_RGB16(redFg, greenFg, blueFg, fgcolor); - } - } - dstData = (BYTE*) _aligned_malloc(width * height * 2, 16); if (!dstData) @@ -1147,6 +1128,17 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp dst16 = (UINT16*) dstData; + if (clrconv->rgb555) + { + bgcolor = clrconv->invert ? BGR15(redBg, greenBg, blueBg) : RGB15(redBg, greenBg, blueBg); + fgcolor = clrconv->invert ? BGR15(redFg, greenFg, blueFg) : RGB15(redFg, greenFg, blueFg); + } + else + { + bgcolor = clrconv->invert ? BGR16(redBg, greenBg, blueBg) : RGB16(redBg, greenBg, blueBg); + fgcolor = clrconv->invert ? BGR16(redFg, greenFg, blueFg) : RGB16(redFg, greenFg, blueFg); + } + for (index = height; index > 0; index--) { /* each bit encodes a pixel */ From 651887c7e07cbe05e331dfb649de229ae70f1d05 Mon Sep 17 00:00:00 2001 From: Pavel Tsekov Date: Thu, 14 Aug 2014 20:21:49 +0300 Subject: [PATCH 10/10] Fix erronous use of colors in gdi_patblt(). * libfreerdp/gdi/gdi.c: (gdi_patblt): Fix a call to freerdp_mono_image_convert() which was still passed colors in drawing order representation instead of GDI representation. --- libfreerdp/gdi/gdi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index e76012f0c..90c5c90d2 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -517,7 +517,7 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) HGDI_BITMAP hBmp; data = freerdp_mono_image_convert(GDI_BS_HATCHED_PATTERNS + 8 * brush->hatch, 8, 8, 1, - gdi->dstBpp, patblt->backColor, patblt->foreColor, gdi->clrconv); + gdi->dstBpp, backColor, foreColor, gdi->clrconv); hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data);