diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index 7bcb393f1..311442667 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -135,10 +135,6 @@ static BOOL xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, UINT32 SrcFormat; UINT32 bytesPerPixel; xfContext* xfc = (xfContext*) context; - - if (!Bitmap_SetDimensions(bitmap, width, height)) - return FALSE; - bytesPerPixel = (bpp + 7) / 8; size = width * height * 4; bitmap->data = (BYTE*) _aligned_malloc(size, 16); diff --git a/include/freerdp/cache/bitmap.h b/include/freerdp/cache/bitmap.h index 3cf515895..ad12c31f8 100644 --- a/include/freerdp/cache/bitmap.h +++ b/include/freerdp/cache/bitmap.h @@ -53,8 +53,6 @@ struct rdp_bitmap_cache UINT32 paddingB[32 - 18]; /* 18 */ /* internal */ - - rdpBitmap* bitmap; rdpUpdate* update; rdpContext* context; rdpSettings* settings; diff --git a/libfreerdp/cache/bitmap.c b/libfreerdp/cache/bitmap.c index 41a0af86d..e4887e473 100644 --- a/libfreerdp/cache/bitmap.c +++ b/libfreerdp/cache/bitmap.c @@ -36,12 +36,12 @@ #define TAG FREERDP_TAG("cache.bitmap") static rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id, - UINT32 index); + UINT32 index); static void bitmap_cache_put(rdpBitmapCache* bitmap_cache, UINT32 id, - UINT32 index, rdpBitmap* bitmap); + UINT32 index, rdpBitmap* bitmap); static BOOL update_gdi_memblt(rdpContext* context, - MEMBLT_ORDER* memblt) + MEMBLT_ORDER* memblt) { rdpBitmap* bitmap; rdpCache* cache = context->cache; @@ -50,7 +50,7 @@ static BOOL update_gdi_memblt(rdpContext* context, bitmap = offscreen_cache_get(cache->offscreen, memblt->cacheIndex); else bitmap = bitmap_cache_get(cache->bitmap, (BYTE) memblt->cacheId, - memblt->cacheIndex); + memblt->cacheIndex); /* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */ if (bitmap == NULL) @@ -61,7 +61,7 @@ static BOOL update_gdi_memblt(rdpContext* context, } static BOOL update_gdi_mem3blt(rdpContext* context, - MEM3BLT_ORDER* mem3blt) + MEM3BLT_ORDER* mem3blt) { BYTE style; rdpBitmap* bitmap; @@ -73,7 +73,7 @@ static BOOL update_gdi_mem3blt(rdpContext* context, bitmap = offscreen_cache_get(cache->offscreen, mem3blt->cacheIndex); else bitmap = bitmap_cache_get(cache->bitmap, (BYTE) mem3blt->cacheId, - mem3blt->cacheIndex); + mem3blt->cacheIndex); /* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */ if (!bitmap) @@ -98,7 +98,7 @@ static BOOL update_gdi_mem3blt(rdpContext* context, } static BOOL update_gdi_cache_bitmap(rdpContext* context, - const CACHE_BITMAP_ORDER* cacheBitmap) + const CACHE_BITMAP_ORDER* cacheBitmap) { rdpBitmap* bitmap; rdpBitmap* prevBitmap; @@ -108,11 +108,14 @@ static BOOL update_gdi_cache_bitmap(rdpContext* context, if (!bitmap) return FALSE; + Bitmap_SetDimensions(bitmap, cacheBitmap->bitmapWidth, + cacheBitmap->bitmapHeight); + if (!bitmap->Decompress(context, bitmap, - cacheBitmap->bitmapDataStream, cacheBitmap->bitmapWidth, - cacheBitmap->bitmapHeight, - cacheBitmap->bitmapBpp, cacheBitmap->bitmapLength, - cacheBitmap->compressed, RDP_CODEC_ID_NONE)) + cacheBitmap->bitmapDataStream, cacheBitmap->bitmapWidth, + cacheBitmap->bitmapHeight, + cacheBitmap->bitmapBpp, cacheBitmap->bitmapLength, + cacheBitmap->compressed, RDP_CODEC_ID_NONE)) { bitmap->Free(context, bitmap); return FALSE; @@ -125,18 +128,18 @@ static BOOL update_gdi_cache_bitmap(rdpContext* context, } prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmap->cacheId, - cacheBitmap->cacheIndex); + cacheBitmap->cacheIndex); if (prevBitmap != NULL) prevBitmap->Free(context, prevBitmap); bitmap_cache_put(cache->bitmap, cacheBitmap->cacheId, cacheBitmap->cacheIndex, - bitmap); + bitmap); return TRUE; } static BOOL update_gdi_cache_bitmap_v2(rdpContext* context, - CACHE_BITMAP_V2_ORDER* cacheBitmapV2) + CACHE_BITMAP_V2_ORDER* cacheBitmapV2) { rdpBitmap* bitmap; @@ -154,35 +157,41 @@ static BOOL update_gdi_cache_bitmap_v2(rdpContext* context, if ((settings->ColorDepth == 15) && (cacheBitmapV2->bitmapBpp == 16)) cacheBitmapV2->bitmapBpp = settings->ColorDepth; + Bitmap_SetDimensions(bitmap, cacheBitmapV2->bitmapWidth, + cacheBitmapV2->bitmapHeight); + if (!bitmap->Decompress(context, bitmap, - cacheBitmapV2->bitmapDataStream, - cacheBitmapV2->bitmapWidth, - cacheBitmapV2->bitmapHeight, - cacheBitmapV2->bitmapBpp, - cacheBitmapV2->bitmapLength, - cacheBitmapV2->compressed, - RDP_CODEC_ID_NONE)) + cacheBitmapV2->bitmapDataStream, + cacheBitmapV2->bitmapWidth, + cacheBitmapV2->bitmapHeight, + cacheBitmapV2->bitmapBpp, + cacheBitmapV2->bitmapLength, + cacheBitmapV2->compressed, + RDP_CODEC_ID_NONE)) { bitmap->Free(context, bitmap); return FALSE; } prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmapV2->cacheId, - cacheBitmapV2->cacheIndex); + cacheBitmapV2->cacheIndex); if (!bitmap->New(context, bitmap)) + { + bitmap->Free(context, bitmap); return FALSE; + } if (prevBitmap) prevBitmap->Free(context, prevBitmap); bitmap_cache_put(cache->bitmap, cacheBitmapV2->cacheId, - cacheBitmapV2->cacheIndex, bitmap); + cacheBitmapV2->cacheIndex, bitmap); return TRUE; } static BOOL update_gdi_cache_bitmap_v3(rdpContext* context, - CACHE_BITMAP_V3_ORDER* cacheBitmapV3) + CACHE_BITMAP_V3_ORDER* cacheBitmapV3) { rdpBitmap* bitmap; rdpBitmap* prevBitmap; @@ -199,74 +208,83 @@ static BOOL update_gdi_cache_bitmap_v3(rdpContext* context, cacheBitmapV3->bpp = settings->ColorDepth; compressed = (bitmapData->codecID != RDP_CODEC_ID_NONE); - bitmap->Decompress(context, bitmap, - bitmapData->data, bitmapData->width, bitmapData->height, - bitmapData->bpp, bitmapData->length, compressed, - bitmapData->codecID); + Bitmap_SetDimensions(bitmap, bitmapData->width, bitmapData->height); + + if (!bitmap->Decompress(context, bitmap, + bitmapData->data, bitmapData->width, bitmapData->height, + bitmapData->bpp, bitmapData->length, compressed, + bitmapData->codecID)) + { + bitmap->Free(context, bitmap); + return FALSE; + } if (!bitmap->New(context, bitmap)) + { + bitmap->Free(context, bitmap); return FALSE; + } prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmapV3->cacheId, - cacheBitmapV3->cacheIndex); + cacheBitmapV3->cacheIndex); if (prevBitmap) prevBitmap->Free(context, prevBitmap); bitmap_cache_put(cache->bitmap, cacheBitmapV3->cacheId, - cacheBitmapV3->cacheIndex, bitmap); + cacheBitmapV3->cacheIndex, bitmap); return TRUE; } static BOOL update_gdi_bitmap_update(rdpContext* context, - const BITMAP_UPDATE* bitmapUpdate) + const BITMAP_UPDATE* bitmapUpdate) { UINT32 i; - BOOL reused = TRUE; - rdpBitmap* bitmap; - rdpCache* cache = context->cache; - - if (!cache->bitmap->bitmap) - { - cache->bitmap->bitmap = Bitmap_Alloc(context); - cache->bitmap->bitmap->ephemeral = TRUE; - reused = FALSE; - } - - bitmap = cache->bitmap->bitmap; for (i = 0; i < bitmapUpdate->number; i++) { const BITMAP_DATA* bitmapData = &bitmapUpdate->rectangles[i]; + rdpBitmap* bitmap = Bitmap_Alloc(context); + + if (!bitmap) + return FALSE; + bitmap->format = gdi_get_pixel_format(bitmapData->bitsPerPixel, FALSE); bitmap->length = bitmapData->bitmapLength; bitmap->compressed = bitmapData->compressed; Bitmap_SetRectangle(bitmap, - bitmapData->destLeft, bitmapData->destTop, - bitmapData->destRight, bitmapData->destBottom); + bitmapData->destLeft, bitmapData->destTop, + bitmapData->destRight, bitmapData->destBottom); - bitmap->Decompress(context, bitmap, - bitmapData->bitmapDataStream, bitmapData->width, bitmapData->height, - bitmapData->bitsPerPixel, bitmapData->bitmapLength, - bitmapData->compressed, RDP_CODEC_ID_NONE); - - if (reused) + if (!bitmap->Decompress(context, bitmap, + bitmapData->bitmapDataStream, bitmapData->width, bitmapData->height, + bitmapData->bitsPerPixel, bitmapData->bitmapLength, + bitmapData->compressed, RDP_CODEC_ID_NONE)) + { bitmap->Free(context, bitmap); - - reused = TRUE; + return FALSE; + } if (!bitmap->New(context, bitmap)) + { + bitmap->Free(context, bitmap); return FALSE; + } if (!bitmap->Paint(context, bitmap)) + { + bitmap->Free(context, bitmap); return FALSE; + } + + bitmap->Free(context, bitmap); } return TRUE; } rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id, - UINT32 index) + UINT32 index) { rdpBitmap* bitmap; @@ -291,7 +309,7 @@ rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id, } void bitmap_cache_put(rdpBitmapCache* bitmapCache, UINT32 id, UINT32 index, - rdpBitmap* bitmap) + rdpBitmap* bitmap) { if (id > bitmapCache->maxCells) { @@ -338,7 +356,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings) bitmapCache->context = bitmapCache->update->context; bitmapCache->maxCells = settings->BitmapCacheV2NumCells; bitmapCache->cells = (BITMAP_V2_CELL*) calloc(bitmapCache->maxCells, - sizeof(BITMAP_V2_CELL)); + sizeof(BITMAP_V2_CELL)); if (!bitmapCache->cells) { @@ -351,7 +369,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings) bitmapCache->cells[i].number = settings->BitmapCacheV2CellInfo[i].numEntries; /* allocate an extra entry for BITMAP_CACHE_WAITING_LIST_INDEX */ bitmapCache->cells[i].entries = (rdpBitmap**) calloc(( - bitmapCache->cells[i].number + 1), sizeof(rdpBitmap*)); + bitmapCache->cells[i].number + 1), sizeof(rdpBitmap*)); } } @@ -378,9 +396,6 @@ void bitmap_cache_free(rdpBitmapCache* bitmapCache) free(bitmapCache->cells[i].entries); } - if (bitmapCache->bitmap) - bitmapCache->bitmap->Free(bitmapCache->context, bitmapCache->bitmap); - free(bitmapCache->cells); free(bitmapCache); } diff --git a/libfreerdp/core/graphics.c b/libfreerdp/core/graphics.c index 56eb4c2bf..935d84035 100644 --- a/libfreerdp/core/graphics.c +++ b/libfreerdp/core/graphics.c @@ -76,6 +76,8 @@ BOOL Bitmap_SetRectangle(rdpBitmap* bitmap, bitmap->top = top; bitmap->right = right; bitmap->bottom = bottom; + bitmap->width = bitmap->right - bitmap->left + 1; + bitmap->height = bitmap->bottom - bitmap->top + 1; return TRUE; } @@ -86,6 +88,8 @@ BOOL Bitmap_SetDimensions(rdpBitmap* bitmap, if (!bitmap) return FALSE; + bitmap->right = bitmap->left + width - 1; + bitmap->bottom = bitmap->top + height - 1; bitmap->width = width; bitmap->height = height; return TRUE; diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 26033fc92..ee836e4e7 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -486,61 +486,40 @@ static BOOL gdi_bitmap_update(rdpContext* context, for (index = 0; index < bitmapUpdate->number; index++) { - const BITMAP_DATA* bitmap = &(bitmapUpdate->rectangles[index]); - UINT32 nXSrc = 0; - UINT32 nYSrc = 0; - UINT32 nXDst = bitmap->destLeft; - UINT32 nYDst = bitmap->destTop; - UINT32 nWidth = MIN(bitmap->destRight, - gdi->width - 1) - bitmap->destLeft + 1; /* clip width */ - UINT32 nHeight = MIN(bitmap->destBottom, - gdi->height - 1) - bitmap->destTop + 1; /* clip height */ - const BYTE* pSrcData = bitmap->bitmapDataStream; - UINT32 SrcSize = bitmap->bitmapLength; - BOOL compressed = bitmap->compressed; - UINT32 bitsPerPixel = bitmap->bitsPerPixel; + const BITMAP_DATA* bitmapData = &(bitmapUpdate->rectangles[index]); + rdpBitmap* bmp = Bitmap_Alloc(context); - if (compressed) - { - if (bitsPerPixel < 32) - { - if (!interleaved_decompress(codecs->interleaved, - pSrcData, SrcSize, - bitmap->width, bitmap->height, - bitsPerPixel, - gdi->primary_buffer, - gdi->primary->hdc->format, - gdi->stride, nXDst, nYDst, - nWidth, nHeight, - &gdi->palette)) - return FALSE; - } - else - { - if (!planar_decompress(codecs->planar, pSrcData, - SrcSize, bitmap->width, bitmap->height, - gdi->primary_buffer, - gdi->primary->hdc->format, - gdi->stride, - nXDst, nYDst, nWidth, nHeight, TRUE)) - return FALSE; - } - } - else - { - UINT32 SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE); - UINT32 nSrcStep = nWidth * GetBytesPerPixel(SrcFormat); + if (!bmp) + return FALSE; - if (!freerdp_image_copy(gdi->primary_buffer, gdi->primary->hdc->format, - gdi->stride, - nXDst, nYDst, nWidth, nHeight, - pSrcData, SrcFormat, nSrcStep, - nXSrc, nYSrc, &gdi->palette)) - return FALSE; + Bitmap_SetRectangle(bmp, bitmapData->destLeft, bitmapData->destTop, + bitmapData->destRight, bitmapData->destBottom); + + if (!bmp->Decompress(context, bmp, bitmapData->bitmapDataStream, + bitmapData->width, bitmapData->height, + bitmapData->bitsPerPixel, bitmapData->bitmapLength, + bitmapData->compressed, RDP_CODEC_ID_NONE)) + { + bmp->Free(context, bmp); + return FALSE; } - if (!gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, - nWidth, nHeight)) + if (!bmp->New(context, bmp)) + { + bmp->Free(context, bmp); + return FALSE; + } + + if (!bmp->Paint(context, bmp)) + { + bmp->Free(context, bmp); + return FALSE; + } + + bmp->Free(context, bmp); + + if (!gdi_InvalidateRegion(gdi->primary->hdc, bmp->left, bmp->top, + bmp->width, bmp->height)) return FALSE; } diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c index 4ec564d01..2ce6f5a4b 100644 --- a/libfreerdp/gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -141,10 +141,6 @@ static BOOL gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, UINT32 DstWidth = width; UINT32 DstHeight = height; rdpGdi* gdi = context->gdi; - - if (!Bitmap_SetDimensions(bitmap, width, height)) - return FALSE; - bytesPerPixel = (bpp + 7) / 8; size = width * height * GetBytesPerPixel(gdi->dstFormat); bitmap->data = (BYTE*) _aligned_malloc(size, 16);