libfreerdp-gdi: start optimizing gdi bitmap update

This commit is contained in:
Marc-André Moreau 2014-09-11 20:12:32 -04:00
parent 938e2abcd4
commit 5b2a465ee6
6 changed files with 434 additions and 89 deletions

View File

@ -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" {

View File

@ -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);

View File

@ -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)

View File

@ -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
{

View File

@ -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;
}

View File

@ -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));