Unified bitmap drawing.
authorArmin Novak <armin.novak@thincast.com>
Wed, 20 Jul 2016 13:34:06 +0000 (15:34 +0200)
committerArmin Novak <armin.novak@thincast.com>
Thu, 6 Oct 2016 11:43:03 +0000 (13:43 +0200)
client/X11/xf_graphics.c
include/freerdp/cache/bitmap.h
libfreerdp/cache/bitmap.c
libfreerdp/core/graphics.c
libfreerdp/gdi/gdi.c
libfreerdp/gdi/graphics.c

index 7bcb393..3114426 100644 (file)
@@ -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);
index 3cf5158..ad12c31 100644 (file)
@@ -53,8 +53,6 @@ struct rdp_bitmap_cache
        UINT32 paddingB[32 - 18]; /* 18 */
 
        /* internal */
-
-       rdpBitmap* bitmap;
        rdpUpdate* update;
        rdpContext* context;
        rdpSettings* settings;
index 41a0af8..e4887e4 100644 (file)
 #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);
-
-               bitmap->Decompress(context, bitmap,
-                                  bitmapData->bitmapDataStream, bitmapData->width, bitmapData->height,
-                                  bitmapData->bitsPerPixel, bitmapData->bitmapLength,
-                                  bitmapData->compressed, RDP_CODEC_ID_NONE);
+                                   bitmapData->destLeft, bitmapData->destTop,
+                                   bitmapData->destRight, bitmapData->destBottom);
 
-               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);
        }
index 56eb4c2..935d840 100644 (file)
@@ -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;
index 26033fc..ee836e4 100644 (file)
@@ -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;
-
-               if (compressed)
+               const BITMAP_DATA* bitmapData = &(bitmapUpdate->rectangles[index]);
+               rdpBitmap* bmp = Bitmap_Alloc(context);
+
+               if (!bmp)
+                       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))
                {
-                       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;
-                       }
+                       bmp->Free(context, bmp);
+                       return FALSE;
                }
-               else
+
+               if (!bmp->New(context, bmp))
                {
-                       UINT32 SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE);
-                       UINT32 nSrcStep = nWidth * GetBytesPerPixel(SrcFormat);
-
-                       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;
+                       bmp->Free(context, bmp);
+                       return FALSE;
                }
 
-               if (!gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst,
-                                         nWidth, nHeight))
+               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;
        }
 
index 4ec564d..2ce6f5a 100644 (file)
@@ -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);