From bd516e04fa6726c3a69966209a0d8f0575c6cd44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 6 Sep 2014 21:13:37 -0400 Subject: [PATCH] libfreerdp-primitives: cleanup YCoCg --- client/X11/xf_client.c | 1 + include/freerdp/primitives.h | 4 +- libfreerdp/codec/planar.c | 4 +- libfreerdp/core/capabilities.c | 13 ++- libfreerdp/core/settings.c | 4 + libfreerdp/primitives/prim_YCoCg.c | 102 ++++++++++-------- libfreerdp/primitives/prim_YCoCg.h | 2 +- libfreerdp/primitives/prim_YCoCg_opt.c | 14 +-- .../primitives/test/TestPrimitivesYCoCg.c | 8 +- 9 files changed, 86 insertions(+), 66 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index a803edf74..d43ed6359 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -810,6 +810,7 @@ BOOL xf_pre_connect(freerdp *instance) xfc->fullscreen_toggle = settings->ToggleFullscreen; xf_detect_monitors(xfc, settings); xfc->colormap = DefaultColormap(xfc->display, xfc->screen_number); + return TRUE; } diff --git a/include/freerdp/primitives.h b/include/freerdp/primitives.h index e75e8c69c..d47300c01 100644 --- a/include/freerdp/primitives.h +++ b/include/freerdp/primitives.h @@ -152,7 +152,7 @@ typedef pstatus_t (*__RGBToRGB_16s8u_P3AC4R_t)( const INT16 *pSrc[3], INT32 srcStep, BYTE *pDst, INT32 dstStep, const prim_size_t *roi); -typedef pstatus_t (*__YCoCgRToRGB_8u_AC4R_t)( +typedef pstatus_t (*__YCoCgToRGB_8u_AC4R_t)( const BYTE *pSrc, INT32 srcStep, BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height, @@ -211,7 +211,7 @@ typedef struct __yCbCrToRGB_16s16s_P3P3_t yCbCrToRGB_16s16s_P3P3; __RGBToYCbCr_16s16s_P3P3_t RGBToYCbCr_16s16s_P3P3; __RGBToRGB_16s8u_P3AC4R_t RGBToRGB_16s8u_P3AC4R; - __YCoCgRToRGB_8u_AC4R_t YCoCgRToRGB_8u_AC4R; + __YCoCgToRGB_8u_AC4R_t YCoCgToRGB_8u_AC4R; __RGB565ToARGB_16u32u_C3C4_t RGB565ToARGB_16u32u_C3C4; __YUV420ToRGB_8u_P3AC4R_t YUV420ToRGB_8u_P3AC4R; } primitives_t; diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c index a48795a21..5a3e35e6a 100644 --- a/libfreerdp/codec/planar.c +++ b/libfreerdp/codec/planar.c @@ -336,7 +336,7 @@ int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcS { static BOOL been_warned = FALSE; if (!been_warned) - DEBUG_WARN( "Chroma-Subsampling is not implemented.\n"); + DEBUG_WARN("Chroma-Subsampling is not implemented.\n"); been_warned = TRUE; } else @@ -346,7 +346,7 @@ int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcS alpha = (FormatHeader & PLANAR_FORMAT_HEADER_NA) ? FALSE : TRUE; cll = FormatHeader & PLANAR_FORMAT_HEADER_CLL_MASK; - primitives_get()->YCoCgRToRGB_8u_AC4R( + primitives_get()->YCoCgToRGB_8u_AC4R( pDstData, nDstStep, pDstData, nDstStep, nWidth, nHeight, cll, alpha, FALSE); } diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index 168f05d8e..91bc8a931 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -361,7 +361,15 @@ void rdp_write_bitmap_capability_set(wStream* s, rdpSettings* settings) header = rdp_capability_set_start(s); - drawingFlags |= DRAW_ALLOW_SKIP_ALPHA; + if (settings->DrawAllowSkipAlpha) + drawingFlags |= DRAW_ALLOW_SKIP_ALPHA; + + if (settings->DrawAllowColorSubsampling) + drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY; + + if (settings->DrawAllowDynamicColorFidelity) + drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING; /* currently unimplemented */ + /* While bitmap_decode.c now implements YCoCg, in turning it * on we have found Microsoft is inconsistent on whether to invert R & B. * And it's not only from one server to another; on Win7/2008R2, it appears @@ -370,9 +378,6 @@ void rdp_write_bitmap_capability_set(wStream* s, rdpSettings* settings) * will not send it. YCoCg is still needed for EGFX, but it at least * appears consistent in its use. */ - /* drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY; */ - /* YCoCg with chroma subsampling is not implemented in bitmap_decode.c. */ - /* drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING; */ if (settings->RdpVersion > 5) preferredBitsPerPixel = settings->ColorDepth; diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 0eec9b087..3c070827d 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -321,6 +321,10 @@ rdpSettings* freerdp_settings_new(DWORD flags) settings->DrawGdiPlusEnabled = FALSE; + settings->DrawAllowSkipAlpha = TRUE; + settings->DrawAllowColorSubsampling = FALSE; + settings->DrawAllowDynamicColorFidelity = FALSE; + settings->FrameMarkerCommandEnabled = TRUE; settings->SurfaceFrameMarkerEnabled = TRUE; settings->BitmapCacheV3Enabled = FALSE; diff --git a/libfreerdp/primitives/prim_YCoCg.c b/libfreerdp/primitives/prim_YCoCg.c index 3e7505676..ca6484795 100644 --- a/libfreerdp/primitives/prim_YCoCg.c +++ b/libfreerdp/primitives/prim_YCoCg.c @@ -33,7 +33,7 @@ #endif /* !MINMAX */ /* ------------------------------------------------------------------------- */ -pstatus_t general_YCoCgRToRGB_8u_AC4R( +pstatus_t general_YCoCgToRGB_8u_AC4R( const BYTE *pSrc, INT32 srcStep, BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height, @@ -41,75 +41,85 @@ pstatus_t general_YCoCgRToRGB_8u_AC4R( BOOL withAlpha, BOOL invert) { - const BYTE *sptr = pSrc; + BYTE A; + int x, y; BYTE *dptr = pDst; + const BYTE *sptr = pSrc; + INT16 Cg, Co, Y, T, R, G, B; int cll = shift - 1; /* -1 builds in the /2's */ - int x,y; - int srcRowBump = srcStep - width*sizeof(UINT32); - int dstRowBump = dstStep - width*sizeof(UINT32); + int srcPad = srcStep - (width * 4); + int dstPad = dstStep - (width * 4); + if (invert) { - for (y=0; yINT16 */ - a = *sptr++; - if (!withAlpha) a = 0xFFU; - t = y - cg; - r = t + co; - g = y + cg; - b = t - co; - *dptr++ = (BYTE) MINMAX(r, 0, 255); - *dptr++ = (BYTE) MINMAX(g, 0, 255); - *dptr++ = (BYTE) MINMAX(b, 0, 255); - *dptr++ = a; + Cg = (INT16) ((INT8) ((*sptr++) << cll)); + Co = (INT16) ((INT8) ((*sptr++) << cll)); + Y = (INT16) (*sptr++); /* UINT8->INT16 */ + + A = *sptr++; + + if (!withAlpha) + A = 0xFFU; + + T = Y - Cg; + R = T + Co; + G = Y + Cg; + B = T - Co; + + *dptr++ = (BYTE) MINMAX(R, 0, 255); + *dptr++ = (BYTE) MINMAX(G, 0, 255); + *dptr++ = (BYTE) MINMAX(B, 0, 255); + *dptr++ = A; } - sptr += srcRowBump; - dptr += dstRowBump; + + sptr += srcPad; + dptr += dstPad; } } else { - for (y=0; yINT16 */ - a = *sptr++; - if (!withAlpha) a = 0xFFU; - t = y - cg; - r = t + co; - g = y + cg; - b = t - co; - *dptr++ = (BYTE) MINMAX(b, 0, 255); - *dptr++ = (BYTE) MINMAX(g, 0, 255); - *dptr++ = (BYTE) MINMAX(r, 0, 255); - *dptr++ = a; + Cg = (INT16) ((INT8) ((*sptr++) << cll)); + Co = (INT16) ((INT8) ((*sptr++) << cll)); + Y = (INT16) (*sptr++); /* UINT8->INT16 */ + + A = *sptr++; + + if (!withAlpha) + A = 0xFFU; + + T = Y - Cg; + R = T + Co; + G = Y + Cg; + B = T - Co; + + *dptr++ = (BYTE) MINMAX(B, 0, 255); + *dptr++ = (BYTE) MINMAX(G, 0, 255); + *dptr++ = (BYTE) MINMAX(R, 0, 255); + *dptr++ = A; } - sptr += srcRowBump; - dptr += dstRowBump; + + sptr += srcPad; + dptr += dstPad; } } + return PRIMITIVES_SUCCESS; } /* ------------------------------------------------------------------------- */ void primitives_init_YCoCg(primitives_t* prims) { - prims->YCoCgRToRGB_8u_AC4R = general_YCoCgRToRGB_8u_AC4R; + prims->YCoCgToRGB_8u_AC4R = general_YCoCgToRGB_8u_AC4R; primitives_init_YCoCg_opt(prims); } diff --git a/libfreerdp/primitives/prim_YCoCg.h b/libfreerdp/primitives/prim_YCoCg.h index aa3929aff..c03715bda 100644 --- a/libfreerdp/primitives/prim_YCoCg.h +++ b/libfreerdp/primitives/prim_YCoCg.h @@ -24,7 +24,7 @@ #ifndef __PRIM_YCOCG_H_INCLUDED__ #define __PRIM_YCOCG_H_INCLUDED__ -pstatus_t general_YCoCgRToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep, BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height, UINT8 shift, BOOL withAlpha, BOOL invert); +pstatus_t general_YCoCgToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep, BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height, UINT8 shift, BOOL withAlpha, BOOL invert); void primitives_init_YCoCg_opt(primitives_t* prims); diff --git a/libfreerdp/primitives/prim_YCoCg_opt.c b/libfreerdp/primitives/prim_YCoCg_opt.c index 51fce1fc3..e022662b3 100644 --- a/libfreerdp/primitives/prim_YCoCg_opt.c +++ b/libfreerdp/primitives/prim_YCoCg_opt.c @@ -69,7 +69,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_invert( if ((width < 8) || (ULONG_PTR) dptr & 0x03) { /* Too small, or we'll never hit a 16-byte boundary. Punt. */ - return general_YCoCgRToRGB_8u_AC4R(pSrc, srcStep, + return general_YCoCgToRGB_8u_AC4R(pSrc, srcStep, pDst, dstStep, width, height, shift, withAlpha, TRUE); } @@ -83,7 +83,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_invert( { int startup = (16 - ((ULONG_PTR) dptr & 0x0f)) / 4; if (startup > width) startup = width; - general_YCoCgRToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, + general_YCoCgToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, startup, 1, shift, withAlpha, TRUE); sptr += startup * sizeof(UINT32); dptr += startup * sizeof(UINT32); @@ -185,7 +185,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_invert( /* Handle any remainder pixels. */ if (w > 0) { - general_YCoCgRToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, + general_YCoCgToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, w, 1, shift, withAlpha, TRUE); sptr += w * sizeof(UINT32); dptr += w * sizeof(UINT32); @@ -228,7 +228,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_no_invert( if ((width < 8) || (ULONG_PTR) dptr & 0x03) { /* Too small, or we'll never hit a 16-byte boundary. Punt. */ - return general_YCoCgRToRGB_8u_AC4R(pSrc, srcStep, + return general_YCoCgToRGB_8u_AC4R(pSrc, srcStep, pDst, dstStep, width, height, shift, withAlpha, FALSE); } @@ -242,7 +242,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_no_invert( { int startup = (16 - ((ULONG_PTR) dptr & 0x0f)) / 4; if (startup > width) startup = width; - general_YCoCgRToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, + general_YCoCgToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, startup, 1, shift, withAlpha, FALSE); sptr += startup * sizeof(UINT32); dptr += startup * sizeof(UINT32); @@ -348,7 +348,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_no_invert( /* Handle any remainder pixels. */ if (w > 0) { - general_YCoCgRToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, + general_YCoCgToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, w, 1, shift, withAlpha, FALSE); sptr += w * sizeof(UINT32); dptr += w * sizeof(UINT32); @@ -393,7 +393,7 @@ void primitives_init_YCoCg_opt(primitives_t* prims) if (IsProcessorFeaturePresentEx(PF_EX_SSSE3) && IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE)) { - prims->YCoCgRToRGB_8u_AC4R = ssse3_YCoCgRToRGB_8u_AC4R; + prims->YCoCgToRGB_8u_AC4R = ssse3_YCoCgRToRGB_8u_AC4R; } #endif /* WITH_SSE2 */ } diff --git a/libfreerdp/primitives/test/TestPrimitivesYCoCg.c b/libfreerdp/primitives/test/TestPrimitivesYCoCg.c index d6f4d4289..c280b5be3 100644 --- a/libfreerdp/primitives/test/TestPrimitivesYCoCg.c +++ b/libfreerdp/primitives/test/TestPrimitivesYCoCg.c @@ -28,7 +28,7 @@ static const float TEST_TIME = 4.0; extern BOOL g_TestPrimitivesPerformance; -extern pstatus_t general_YCoCgRToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep, +extern pstatus_t general_YCoCgToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep, BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height, UINT8 shift, BOOL withAlpha, BOOL invert); extern pstatus_t ssse3_YCoCgRToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep, @@ -48,9 +48,9 @@ int test_YCoCgRToRGB_8u_AC4R_func(void) testStr[0] = '\0'; get_random_data(in, sizeof(in)); - general_YCoCgRToRGB_8u_AC4R((const BYTE *) (in+1), 63*4, + general_YCoCgToRGB_8u_AC4R((const BYTE *) (in+1), 63*4, (BYTE *) out_c, 63*4, 63, 61, 2, TRUE, FALSE); - general_YCoCgRToRGB_8u_AC4R((const BYTE *) (in+1), 63*4, + general_YCoCgToRGB_8u_AC4R((const BYTE *) (in+1), 63*4, (BYTE *) out_c_inv, 63*4, 63, 61, 2, TRUE, TRUE); #ifdef WITH_SSE2 if (IsProcessorFeaturePresentEx(PF_EX_SSSE3)) @@ -86,7 +86,7 @@ int test_YCoCgRToRGB_8u_AC4R_func(void) /* ------------------------------------------------------------------------- */ STD_SPEED_TEST( ycocg_to_rgb_speed, const BYTE, BYTE, PRIM_NOP, - TRUE, general_YCoCgRToRGB_8u_AC4R(src1, 64*4, dst, 64*4, 64, 64, 2, FALSE, FALSE), + TRUE, general_YCoCgToRGB_8u_AC4R(src1, 64*4, dst, 64*4, 64, 64, 2, FALSE, FALSE), #ifdef WITH_SSE2 TRUE, ssse3_YCoCgRToRGB_8u_AC4R(src1, 64*4, dst, 64*4, 64, 64, 2, FALSE, FALSE), PF_EX_SSSE3, TRUE,