diff --git a/include/freerdp/codec/color.h b/include/freerdp/codec/color.h index 47c6126e3..855a9b330 100644 --- a/include/freerdp/codec/color.h +++ b/include/freerdp/codec/color.h @@ -108,56 +108,101 @@ /* 24bpp formats */ -#define PIXEL_FORMAT_R8G8B8 FREERDP_PIXEL_FORMAT(0, 24, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 8, 8, 8) +#define PIXEL_FORMAT_R8G8B8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 24, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 8, 8, 8) +#define PIXEL_FORMAT_R8G8B8 PIXEL_FORMAT_R8G8B8_F(0) #define PIXEL_FORMAT_RGB24 PIXEL_FORMAT_R8G8B8 +#define PIXEL_FORMAT_R8G8B8_VF PIXEL_FORMAT_R8G8B8_F(1) +#define PIXEL_FORMAT_RGB24_VF PIXEL_FORMAT_R8G8B8_VF -#define PIXEL_FORMAT_B8G8R8 FREERDP_PIXEL_FORMAT(0, 24, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 8, 8, 8) +#define PIXEL_FORMAT_B8G8R8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 24, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 8, 8, 8) +#define PIXEL_FORMAT_B8G8R8 PIXEL_FORMAT_B8G8R8_F(0) #define PIXEL_FORMAT_BGR24 PIXEL_FORMAT_B8G8R8 +#define PIXEL_FORMAT_B8G8R8_VF PIXEL_FORMAT_B8G8R8_F(1) +#define PIXEL_FORMAT_BGR24_VF PIXEL_FORMAT_B8G8R8_VF /* 16bpp formats */ -#define PIXEL_FORMAT_R5G6B5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 6, 5) +#define PIXEL_FORMAT_R5G6B5_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 6, 5) +#define PIXEL_FORMAT_R5G6B5 PIXEL_FORMAT_R5G6B5_F(0) #define PIXEL_FORMAT_RGB565 PIXEL_FORMAT_R5G6B5 #define PIXEL_FORMAT_RGB16 PIXEL_FORMAT_R5G6B5 +#define PIXEL_FORMAT_R5G6B5_VF PIXEL_FORMAT_R5G6B5_F(1) +#define PIXEL_FORMAT_RGB565_VF PIXEL_FORMAT_R5G6B5_VF +#define PIXEL_FORMAT_RGB16_VF PIXEL_FORMAT_R5G6B5_VF -#define PIXEL_FORMAT_B5G6R5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 6, 5) +#define PIXEL_FORMAT_B5G6R5_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 6, 5) +#define PIXEL_FORMAT_B5G6R5 PIXEL_FORMAT_B5G6R5_F(0) #define PIXEL_FORMAT_BGR565 PIXEL_FORMAT_B5G6R5 #define PIXEL_FORMAT_BGR16 PIXEL_FORMAT_B5G6R5 +#define PIXEL_FORMAT_B5G6R5_VF PIXEL_FORMAT_B5G6R5_F(1) +#define PIXEL_FORMAT_BGR565_VF PIXEL_FORMAT_B5G6R5_VF +#define PIXEL_FORMAT_BGR16_VF PIXEL_FORMAT_B5G6R5_VF -#define PIXEL_FORMAT_A1R5G5B5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 1, 5, 5, 5) +#define PIXEL_FORMAT_A1R5G5B5_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 1, 5, 5, 5) +#define PIXEL_FORMAT_A1R5G5B5 PIXEL_FORMAT_A1R5G5B5_F(0) #define PIXEL_FORMAT_ARGB555 PIXEL_FORMAT_A1R5G5B5 #define PIXEL_FORMAT_ARGB15 PIXEL_FORMAT_A1R5G5B5 +#define PIXEL_FORMAT_A1R5G5B5_VF PIXEL_FORMAT_A1R5G5B5_F(1) +#define PIXEL_FORMAT_ARGB555_VF PIXEL_FORMAT_A1R5G5B5_VF +#define PIXEL_FORMAT_ARGB15_VF PIXEL_FORMAT_A1R5G5B5_VF -#define PIXEL_FORMAT_X1R5G5B5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 5, 5) +#define PIXEL_FORMAT_X1R5G5B5_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 5, 5) +#define PIXEL_FORMAT_X1R5G5B5 PIXEL_FORMAT_X1R5G5B5_F(0) #define PIXEL_FORMAT_XRGB555 PIXEL_FORMAT_X1R5G5B5 #define PIXEL_FORMAT_RGB555 PIXEL_FORMAT_X1R5G5B5 #define PIXEL_FORMAT_RGB15 PIXEL_FORMAT_X1R5G5B5 +#define PIXEL_FORMAT_X1R5G5B5_VF PIXEL_FORMAT_X1R5G5B5_F(1) +#define PIXEL_FORMAT_XRGB555_VF PIXEL_FORMAT_X1R5G5B5_VF +#define PIXEL_FORMAT_RGB555_VF PIXEL_FORMAT_X1R5G5B5_VF +#define PIXEL_FORMAT_RGB15_VF PIXEL_FORMAT_X1R5G5B5_VF -#define PIXEL_FORMAT_A1B5G5R5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 1, 5, 5, 5) +#define PIXEL_FORMAT_A1B5G5R5_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 1, 5, 5, 5) +#define PIXEL_FORMAT_A1B5G5R5 PIXEL_FORMAT_A1B5G5R5_F(0) #define PIXEL_FORMAT_ABGR555 PIXEL_FORMAT_A1B5G5R5 #define PIXEL_FORMAT_ABGR15 PIXEL_FORMAT_A1B5G5R5 +#define PIXEL_FORMAT_A1B5G5R5_VF PIXEL_FORMAT_A1B5G5R5_F(1) +#define PIXEL_FORMAT_ABGR555_VF PIXEL_FORMAT_A1B5G5R5_VF +#define PIXEL_FORMAT_ABGR15_VF PIXEL_FORMAT_A1B5G5R5_VF -#define PIXEL_FORMAT_X1B5G5R5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 5, 5) +#define PIXEL_FORMAT_X1B5G5R5_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 5, 5) +#define PIXEL_FORMAT_X1B5G5R5 PIXEL_FORMAT_X1B5G5R5_F(0) #define PIXEL_FORMAT_XBGR555 PIXEL_FORMAT_X1B5G5R5 #define PIXEL_FORMAT_BGR555 PIXEL_FORMAT_X1B5G5R5 #define PIXEL_FORMAT_BGR15 PIXEL_FORMAT_X1B5G5R5 +#define PIXEL_FORMAT_X1B5G5R5_VF PIXEL_FORMAT_X1B5G5R5_F(1) +#define PIXEL_FORMAT_XBGR555_VF PIXEL_FORMAT_X1B5G5R5_VF +#define PIXEL_FORMAT_BGR555_VF PIXEL_FORMAT_X1B5G5R5_VF +#define PIXEL_FORMAT_BGR15_VF PIXEL_FORMAT_X1B5G5R5_VF /* 8bpp formats */ -#define PIXEL_FORMAT_A8 FREERDP_PIXEL_FORMAT(0, 8, FREERDP_PIXEL_FORMAT_TYPE_A, 8, 0, 0, 0) +#define PIXEL_FORMAT_A8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 8, FREERDP_PIXEL_FORMAT_TYPE_A, 8, 0, 0, 0) +#define PIXEL_FORMAT_A8 PIXEL_FORMAT_A8_F(0) #define PIXEL_FORMAT_8BPP PIXEL_FORMAT_A8 #define PIXEL_FORMAT_256 PIXEL_FORMAT_A8 +#define PIXEL_FORMAT_RGB8 PIXEL_FORMAT_A8 +#define PIXEL_FORMAT_A8_VF PIXEL_FORMAT_A8_F(1) +#define PIXEL_FORMAT_8BPP_VF PIXEL_FORMAT_A8_VF +#define PIXEL_FORMAT_256_VF PIXEL_FORMAT_A8_VF +#define PIXEL_FORMAT_RGB8_VF PIXEL_FORMAT_A8_VF /* 4 bpp formats */ -#define PIXEL_FORMAT_A4 FREERDP_PIXEL_FORMAT(0, 4, FREERDP_PIXEL_FORMAT_TYPE_A, 4, 0, 0, 0) +#define PIXEL_FORMAT_A4_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 4, FREERDP_PIXEL_FORMAT_TYPE_A, 4, 0, 0, 0) +#define PIXEL_FORMAT_A4 PIXEL_FORMAT_A4_F(0) #define PIXEL_FORMAT_4BPP PIXEL_FORMAT_A4 +#define PIXEL_FORMAT_A4_VF PIXEL_FORMAT_A4_F(1) +#define PIXEL_FORMAT_4BPP_VF PIXEL_FORMAT_A4_VF /* 1bpp formats */ -#define PIXEL_FORMAT_A1 FREERDP_PIXEL_FORMAT(0, 1, FREERDP_PIXEL_FORMAT_TYPE_A, 1, 0, 0, 0) +#define PIXEL_FORMAT_A1_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 1, FREERDP_PIXEL_FORMAT_TYPE_A, 1, 0, 0, 0) +#define PIXEL_FORMAT_A1 PIXEL_FORMAT_A1_F(0) #define PIXEL_FORMAT_1BPP PIXEL_FORMAT_A1 #define PIXEL_FORMAT_MONO PIXEL_FORMAT_A1 +#define PIXEL_FORMAT_A1_VF PIXEL_FORMAT_A1_F(1) +#define PIXEL_FORMAT_1BPP_VF PIXEL_FORMAT_A1_VF +#define PIXEL_FORMAT_MONO_VF PIXEL_FORMAT_A1_VF #ifdef __cplusplus extern "C" { diff --git a/libfreerdp/cache/bitmap.c b/libfreerdp/cache/bitmap.c index 480ead2f6..afffaa914 100644 --- a/libfreerdp/cache/bitmap.c +++ b/libfreerdp/cache/bitmap.c @@ -41,8 +41,9 @@ void update_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) bitmap = offscreen_cache_get(cache->offscreen, memblt->cacheIndex); else bitmap = bitmap_cache_get(cache->bitmap, (BYTE) memblt->cacheId, memblt->cacheIndex); - /* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */ - if (bitmap == NULL) return; + + if (!bitmap) + return; /* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */ memblt->bitmap = bitmap; IFCALL(cache->bitmap->MemBlt, context, memblt); @@ -60,9 +61,8 @@ void update_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) else bitmap = bitmap_cache_get(cache->bitmap, (BYTE) mem3blt->cacheId, mem3blt->cacheIndex); - /* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */ if (!bitmap) - return; + return; /* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */ style = brush->style; @@ -96,7 +96,7 @@ void update_gdi_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* cacheBitma prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmap->cacheId, cacheBitmap->cacheIndex); - if (prevBitmap != NULL) + if (prevBitmap) Bitmap_Free(context, prevBitmap); bitmap_cache_put(cache->bitmap, cacheBitmap->cacheId, cacheBitmap->cacheIndex, bitmap); @@ -112,11 +112,8 @@ void update_gdi_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cach Bitmap_SetDimensions(context, bitmap, cacheBitmapV2->bitmapWidth, cacheBitmapV2->bitmapHeight); - if (cacheBitmapV2->bitmapBpp == 0) - { - /* Workaround for Windows 8 bug where bitmapBpp is not set */ - cacheBitmapV2->bitmapBpp = context->instance->settings->ColorDepth; - } + if (!cacheBitmapV2->bitmapBpp) + cacheBitmapV2->bitmapBpp = context->settings->ColorDepth; bitmap->Decompress(context, bitmap, cacheBitmapV2->bitmapDataStream, cacheBitmapV2->bitmapWidth, cacheBitmapV2->bitmapHeight, @@ -145,11 +142,8 @@ void update_gdi_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cach Bitmap_SetDimensions(context, bitmap, bitmapData->width, bitmapData->height); - if (cacheBitmapV3->bitmapData.bpp == 0) - { - /* Workaround for Windows 8 bug where bitmapBpp is not set */ - cacheBitmapV3->bitmapData.bpp = context->instance->settings->ColorDepth; - } + if (!cacheBitmapV3->bpp) + cacheBitmapV3->bpp = context->settings->ColorDepth; /* According to http://msdn.microsoft.com/en-us/library/gg441209.aspx * CACHE_BITMAP_REV3_ORDER::bitmapData::codecID = 0x00 (uncompressed) */ @@ -173,9 +167,9 @@ void update_gdi_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cach void update_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) { int i; - rdpBitmap* bitmap; - BITMAP_DATA* bitmap_data; BOOL reused = TRUE; + rdpBitmap* bitmap; + BITMAP_DATA* bitmapData; rdpCache* cache = context->cache; if (!cache->bitmap->bitmap) @@ -189,22 +183,22 @@ void update_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) for (i = 0; i < (int) bitmapUpdate->number; i++) { - bitmap_data = &bitmapUpdate->rectangles[i]; + bitmapData = &bitmapUpdate->rectangles[i]; - bitmap->bpp = bitmap_data->bitsPerPixel; - bitmap->length = bitmap_data->bitmapLength; - bitmap->compressed = bitmap_data->compressed; + bitmap->bpp = bitmapData->bitsPerPixel; + bitmap->length = bitmapData->bitmapLength; + bitmap->compressed = bitmapData->compressed; Bitmap_SetRectangle(context, bitmap, - bitmap_data->destLeft, bitmap_data->destTop, - bitmap_data->destRight, bitmap_data->destBottom); + bitmapData->destLeft, bitmapData->destTop, + bitmapData->destRight, bitmapData->destBottom); - Bitmap_SetDimensions(context, bitmap, bitmap_data->width, bitmap_data->height); + Bitmap_SetDimensions(context, bitmap, bitmapData->width, bitmapData->height); bitmap->Decompress(context, bitmap, - bitmap_data->bitmapDataStream, bitmap_data->width, bitmap_data->height, - bitmap_data->bitsPerPixel, bitmap_data->bitmapLength, - bitmap_data->compressed, RDP_CODEC_ID_NONE); + bitmapData->bitmapDataStream, bitmapData->width, bitmapData->height, + bitmapData->bitsPerPixel, bitmapData->bitmapLength, + bitmapData->compressed, RDP_CODEC_ID_NONE); if (reused) bitmap->Free(context, bitmap); @@ -324,10 +318,8 @@ void bitmap_cache_free(rdpBitmapCache* bitmapCache) { bitmap = bitmapCache->cells[i].entries[j]; - if (bitmap != NULL) - { + if (bitmap) Bitmap_Free(bitmapCache->context, bitmap); - } } free(bitmapCache->cells[i].entries); diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index 2c1c8c2d8..76c3800f6 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -1299,6 +1299,8 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs int x, y; int srcFlip; int dstFlip; + int nSrcPad; + int nDstPad; BYTE a, r, g, b; int beg, end, inc; int srcBitsPerPixel; @@ -1312,10 +1314,19 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs srcBytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(dwSrcFormat) / 8); srcFlip = FREERDP_PIXEL_FORMAT_FLIP(dwSrcFormat); + if (nSrcStep < 0) + nSrcStep = srcBytesPerPixel * nWidth; + dstBitsPerPixel = FREERDP_PIXEL_FORMAT_DEPTH(dwDstFormat); dstBytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(dwDstFormat) / 8); dstFlip = FREERDP_PIXEL_FORMAT_FLIP(dwDstFormat); + if (nDstStep < 0) + nDstStep = dstBytesPerPixel * nWidth; + + nSrcPad = (nSrcStep - (nWidth * srcBytesPerPixel)); + nDstPad = (nDstStep - (nWidth * dstBytesPerPixel)); + if (srcFlip != dstFlip) vFlip = TRUE; @@ -1327,9 +1338,6 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs if (srcBytesPerPixel == 4) { - if (nSrcStep < 0) - nSrcStep = srcBytesPerPixel * nWidth; - if (srcBitsPerPixel == 24) { if (dstBytesPerPixel == 4) /* srcBytesPerPixel == dstBytesPerPixel */ @@ -1339,11 +1347,8 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs UINT32* pSrcPixel; UINT32* pDstPixel; - if (nDstStep < 0) - nDstStep = dstBytesPerPixel * nWidth; - - pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * srcBytesPerPixel)]; - pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * dstBytesPerPixel)]; + pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)]; + pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; for (y = 0; y < nHeight; y++) { @@ -1356,18 +1361,17 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs pDstPixel++; } - pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[(nSrcStep - (nWidth * srcBytesPerPixel))]; - pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[(nDstStep - (nWidth * dstBytesPerPixel))]; + pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcPad]; + pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad]; } + + return 1; } else if (dstBitsPerPixel == 24) /* srcBitsPerPixel == dstBitsPerPixel */ { UINT32* pSrcPixel; UINT32* pDstPixel; - if (nDstStep < 0) - nDstStep = dstBytesPerPixel * nWidth; - if (overlap && (nYSrc < nYDst)) { beg = nHeight - 1; @@ -1385,8 +1389,8 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs { for (y = beg; y != end; y += inc) { - pSrcPixel = (UINT32*) &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * srcBytesPerPixel)]; - pDstPixel = (UINT32*) &pDstData[((nYDst + y) * nDstStep) + (nXDst * dstBytesPerPixel)]; + pSrcPixel = (UINT32*) &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)]; + pDstPixel = (UINT32*) &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)]; MoveMemory(pDstPixel, pSrcPixel, nWidth * 4); } } @@ -1394,11 +1398,13 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs { for (y = beg; y != end; y += inc) { - pSrcPixel = (UINT32*) &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * srcBytesPerPixel)]; - pDstPixel = (UINT32*) &pDstData[((nYDst + (nHeight - y - 1)) * nDstStep) + (nXDst * dstBytesPerPixel)]; + pSrcPixel = (UINT32*) &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)]; + pDstPixel = (UINT32*) &pDstData[((nYDst + (nHeight - y - 1)) * nDstStep) + (nXDst * 4)]; MoveMemory(pDstPixel, pSrcPixel, nWidth * 4); } } + + return 1; } } else if (dstBytesPerPixel == 3) @@ -1406,11 +1412,8 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs UINT32* pSrcPixel; BYTE* pDstPixel; - if (nDstStep < 0) - nDstStep = dstBytesPerPixel * nWidth; - - pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * srcBytesPerPixel)]; - pDstPixel = (BYTE*) &pDstData[(nYDst * nDstStep) + (nXDst * dstBytesPerPixel)]; + pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)]; + pDstPixel = (BYTE*) &pDstData[(nYDst * nDstStep) + (nXDst * 3)]; for (y = 0; y < nHeight; y++) { @@ -1425,9 +1428,11 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs pSrcPixel++; } - pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[(nSrcStep - (nWidth * srcBytesPerPixel))]; - pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[(nDstStep - (nWidth * dstBytesPerPixel))]; + pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcStep]; + pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[nDstStep]; } + + return 1; } else if (dstBytesPerPixel == 2) { @@ -1436,11 +1441,8 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs UINT32* pSrcPixel; UINT16* pDstPixel; - if (nDstStep < 0) - nDstStep = dstBytesPerPixel * nWidth; - - pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * srcBytesPerPixel)]; - pDstPixel = (UINT16*) &pDstData[(nYDst * nDstStep) + (nXDst * dstBytesPerPixel)]; + pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)]; + pDstPixel = (UINT16*) &pDstData[(nYDst * nDstStep) + (nXDst * 2)]; for (y = 0; y < nHeight; y++) { @@ -1454,20 +1456,19 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs pDstPixel++; } - pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[(nSrcStep - (nWidth * srcBytesPerPixel))]; - pDstPixel = (UINT16*) &((BYTE*) pDstPixel)[(nDstStep - (nWidth * dstBytesPerPixel))]; + pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcPad]; + pDstPixel = (UINT16*) &((BYTE*) pDstPixel)[nDstPad]; } + + return 1; } else if (dstBitsPerPixel == 15) { UINT32* pSrcPixel; UINT16* pDstPixel; - if (nDstStep < 0) - nDstStep = dstBytesPerPixel * nWidth; - - pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * srcBytesPerPixel)]; - pDstPixel = (UINT16*) &pDstData[(nYDst * nDstStep) + (nXDst * dstBytesPerPixel)]; + pSrcPixel = (UINT32*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)]; + pDstPixel = (UINT16*) &pDstData[(nYDst * nDstStep) + (nXDst * 2)]; for (y = 0; y < nHeight; y++) { @@ -1481,15 +1482,182 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs pDstPixel++; } - pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[(nSrcStep - (nWidth * srcBytesPerPixel))]; - pDstPixel = (UINT16*) &((BYTE*) pDstPixel)[(nDstStep - (nWidth * dstBytesPerPixel))]; + pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcPad]; + pDstPixel = (UINT16*) &((BYTE*) pDstPixel)[nDstPad]; + } + + return 1; + } + } + } + } + else if (srcBytesPerPixel == 3) + { + if (dstBytesPerPixel == 4) + { + if ((dstBitsPerPixel == 32) || (dstBitsPerPixel == 24)) + { + BYTE* pSrcPixel; + BYTE* pDstPixel; + + if (!vFlip) + { + pSrcPixel = (BYTE*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 3)]; + pDstPixel = (BYTE*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; + + for (y = 0; y < nHeight; y++) + { + for (x = 0; x < nWidth; x++) + { + *pDstPixel++ = *pSrcPixel++; + *pDstPixel++ = *pSrcPixel++; + *pDstPixel++ = *pSrcPixel++; + *pDstPixel++ = 0xFF; + } + + pSrcPixel = (BYTE*) &((BYTE*) pSrcPixel)[nSrcPad]; + pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[nDstPad]; + } + } + else + { + pSrcPixel = (BYTE*) &pSrcData[((nYSrc + nHeight - 1) * nSrcStep) + (nXSrc * 3)]; + pDstPixel = (BYTE*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; + + for (y = 0; y < nHeight; y++) + { + for (x = 0; x < nWidth; x++) + { + *pDstPixel++ = *pSrcPixel++; + *pDstPixel++ = *pSrcPixel++; + *pDstPixel++ = *pSrcPixel++; + *pDstPixel++ = 0xFF; + } + + pSrcPixel = (BYTE*) &((BYTE*) pSrcPixel)[-((nSrcStep - nSrcPad) + nSrcStep)]; + pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[nDstPad]; + } + } + + return 1; + } + } + } + else if (srcBytesPerPixel == 2) + { + if (srcBitsPerPixel == 16) + { + if (dstBytesPerPixel == 4) + { + if ((dstBitsPerPixel == 32) || (dstBitsPerPixel == 24)) + { + UINT16* pSrcPixel; + UINT32* pDstPixel; + + if (!vFlip) + { + pSrcPixel = (UINT16*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 2)]; + pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; + + for (y = 0; y < nHeight; y++) + { + for (x = 0; x < nWidth; x++) + { + GetRGB16(r, g, b, *pSrcPixel); + *pDstPixel = ARGB32(0xFF, r, g, b); + + pSrcPixel++; + pDstPixel++; + } + + pSrcPixel = (UINT16*) &((BYTE*) pSrcPixel)[nSrcPad]; + pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad]; + } + } + else + { + pSrcPixel = (UINT16*) &pSrcData[((nYSrc + nHeight - 1) * nSrcStep) + (nXSrc * 2)]; + pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; + + for (y = 0; y < nHeight; y++) + { + for (x = 0; x < nWidth; x++) + { + GetRGB16(r, g, b, *pSrcPixel); + *pDstPixel = ARGB32(0xFF, r, g, b); + + pSrcPixel++; + pDstPixel++; + } + + pSrcPixel = (UINT16*) &((BYTE*) pSrcPixel)[-((nSrcStep - nSrcPad) + nSrcStep)]; + pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad]; + } + } + + return 1; + } + } + } + else if (srcBitsPerPixel == 15) + { + if (dstBytesPerPixel == 4) + { + if ((dstBitsPerPixel == 32) || (dstBitsPerPixel == 24)) + { + UINT16* pSrcPixel; + UINT32* pDstPixel; + + if (!vFlip) + { + pSrcPixel = (UINT16*) &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 2)]; + pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; + + for (y = 0; y < nHeight; y++) + { + for (x = 0; x < nWidth; x++) + { + GetRGB15(r, g, b, *pSrcPixel); + *pDstPixel = ARGB32(0xFF, r, g, b); + + pSrcPixel++; + pDstPixel++; + } + + pSrcPixel = (UINT16*) &((BYTE*) pSrcPixel)[nSrcPad]; + pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad]; + } + } + else + { + pSrcPixel = (UINT16*) &pSrcData[((nYSrc + nHeight - 1) * nSrcStep) + (nXSrc * 2)]; + pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; + + for (y = 0; y < nHeight; y++) + { + for (x = 0; x < nWidth; x++) + { + GetRGB15(r, g, b, *pSrcPixel); + *pDstPixel = ARGB32(0xFF, r, g, b); + + pSrcPixel++; + pDstPixel++; + } + + pSrcPixel = (UINT16*) &((BYTE*) pSrcPixel)[-((nSrcStep - nSrcPad) + nSrcStep)]; + pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad]; + } } } } } } + else if (srcBytesPerPixel == 1) + { - return 0; + } + + return -1; } void* freerdp_image_memset32(UINT32* ptr, UINT32 fill, size_t length) diff --git a/libfreerdp/codec/interleaved.c b/libfreerdp/codec/interleaved.c index 05525156f..87845a39c 100644 --- a/libfreerdp/codec/interleaved.c +++ b/libfreerdp/codec/interleaved.c @@ -267,8 +267,15 @@ int interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pSrcDa if (!interleaved->FlipBuffer) return -1; - RleDecompress24to24(pSrcData, SrcSize, interleaved->FlipBuffer, scanline, nWidth, nHeight); - freerdp_bitmap_flip(interleaved->FlipBuffer, pDstData, scanline, nHeight); + if (vFlip) + { + RleDecompress24to24(pSrcData, SrcSize, interleaved->FlipBuffer, scanline, nWidth, nHeight); + freerdp_bitmap_flip(interleaved->FlipBuffer, pDstData, scanline, nHeight); + } + else + { + RleDecompress24to24(pSrcData, SrcSize, pDstData, scanline, nWidth, nHeight); + } } else if ((bpp == 16) || (bpp == 15)) { @@ -284,8 +291,15 @@ int interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pSrcDa if (!interleaved->FlipBuffer) return -1; - RleDecompress16to16(pSrcData, SrcSize, interleaved->FlipBuffer, scanline, nWidth, nHeight); - freerdp_bitmap_flip(interleaved->FlipBuffer, pDstData, scanline, nHeight); + if (vFlip) + { + RleDecompress16to16(pSrcData, SrcSize, interleaved->FlipBuffer, scanline, nWidth, nHeight); + freerdp_bitmap_flip(interleaved->FlipBuffer, pDstData, scanline, nHeight); + } + else + { + RleDecompress16to16(pSrcData, SrcSize, pDstData, scanline, nWidth, nHeight); + } } else if (bpp == 8) { @@ -301,8 +315,15 @@ int interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pSrcDa if (!interleaved->FlipBuffer) return -1; - RleDecompress8to8(pSrcData, SrcSize, interleaved->FlipBuffer, scanline, nWidth, nHeight); - freerdp_bitmap_flip(interleaved->FlipBuffer, pDstData, scanline, nHeight); + if (vFlip) + { + RleDecompress8to8(pSrcData, SrcSize, interleaved->FlipBuffer, scanline, nWidth, nHeight); + freerdp_bitmap_flip(interleaved->FlipBuffer, pDstData, scanline, nHeight); + } + else + { + RleDecompress8to8(pSrcData, SrcSize, pDstData, scanline, nWidth, nHeight); + } } else { diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 24f96a924..2aec24ec2 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -454,6 +454,123 @@ void gdi_bitmap_free_ex(gdiBitmap* bitmap) } } +void gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) +{ + int status; + int nXDst; + int nYDst; + int nXSrc; + int nYSrc; + int nWidth; + int nHeight; + int nSrcStep; + int nDstStep; + UINT32 index; + BYTE* buffer; + BYTE* pSrcData; + BYTE* pDstData; + UINT32 SrcSize; + BOOL compressed; + UINT32 SrcFormat; + UINT32 bitsPerPixel; + UINT32 bytesPerPixel; + BITMAP_DATA* bitmap; + rdpGdi* gdi = context->gdi; + rdpCodecs* codecs = context->codecs; + + buffer = (BYTE*) _aligned_malloc(256 * 256 * 4, 16); + + for (index = 0; index < bitmapUpdate->number; index++) + { + bitmap = &(bitmapUpdate->rectangles[index]); + + nXSrc = 0; + nYSrc = 0; + + nXDst = bitmap->destLeft; + nYDst = bitmap->destTop; + + nWidth = bitmap->width; + nHeight = bitmap->height; + + pDstData = buffer; + + pSrcData = bitmap->bitmapDataStream; + SrcSize = bitmap->bitmapLength; + + compressed = bitmap->compressed; + bitsPerPixel = bitmap->bitsPerPixel; + bytesPerPixel = (bitsPerPixel + 7) / 8; + + SrcFormat = PIXEL_FORMAT_XRGB32_VF; + + switch (bitsPerPixel) + { + case 8: + SrcFormat = PIXEL_FORMAT_RGB8_VF; + break; + + case 15: + SrcFormat = PIXEL_FORMAT_RGB15_VF; + break; + + case 16: + SrcFormat = PIXEL_FORMAT_RGB16_VF; + break; + + case 24: + SrcFormat = PIXEL_FORMAT_RGB24_VF; + break; + + case 32: + SrcFormat = PIXEL_FORMAT_XRGB32_VF; + break; + } + + if (compressed) + { + if (bitsPerPixel < 32) + { + freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED); + + status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel, + &pDstData, PIXEL_FORMAT_XRGB32, nWidth * 4, 0, 0, nWidth, nHeight); + } + else + { + freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR); + + status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData, + PIXEL_FORMAT_XRGB32_VF, nWidth * 4, 0, 0, nWidth, nHeight); + } + + if (status < 0) + { + DEBUG_WARN("gdi_bitmap_update: bitmap decompression failure\n"); + return; + } + + pSrcData = buffer; + } + else + { + + } + + nSrcStep = nWidth * bytesPerPixel; + + pDstData = gdi->primary_buffer; + nDstStep = gdi->width * 4; + + status = freerdp_image_copy(pDstData, PIXEL_FORMAT_XRGB32, nDstStep, nXDst, nYDst, + nWidth, nHeight, pSrcData, SrcFormat, nSrcStep, nXSrc, nYSrc); + + gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, nWidth, nHeight); + } + + _aligned_free(buffer); +} + void gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) { rdpGdi* gdi = context->gdi; @@ -1100,6 +1217,8 @@ int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer) gdi_register_graphics(instance->context->graphics); + instance->update->BitmapUpdate = gdi_bitmap_update; + return 0; } diff --git a/libfreerdp/gdi/region.c b/libfreerdp/gdi/region.c index a0869f99e..ec7345cc0 100644 --- a/libfreerdp/gdi/region.c +++ b/libfreerdp/gdi/region.c @@ -371,15 +371,15 @@ INLINE int gdi_InvalidateRegion(HGDI_DC hdc, int x, int y, int w, int h) HGDI_RGN invalid; HGDI_RGN cinvalid; - if (hdc->hwnd == NULL) + if (!hdc->hwnd) return 0; - if (hdc->hwnd->invalid == NULL) + if (!hdc->hwnd->invalid) return 0; cinvalid = hdc->hwnd->cinvalid; - if (hdc->hwnd->ninvalid + 1 > hdc->hwnd->count) + if ((hdc->hwnd->ninvalid + 1) > hdc->hwnd->count) { hdc->hwnd->count *= 2; cinvalid = (HGDI_RGN) realloc(cinvalid, sizeof(GDI_RGN) * (hdc->hwnd->count));