diff --git a/include/freerdp/secondary.h b/include/freerdp/secondary.h index 382b3222b..305327e30 100644 --- a/include/freerdp/secondary.h +++ b/include/freerdp/secondary.h @@ -91,7 +91,10 @@ struct _CACHE_BITMAP_V2_ORDER uint32 bitmapLength; uint32 cacheIndex; boolean compressed; - uint8 bitmapComprHdr[8]; + uint32 cbCompFirstRowSize; + uint32 cbCompMainBodySize; + uint32 cbScanWidth; + uint32 cbUncompressedSize; uint8* bitmapDataStream; }; typedef struct _CACHE_BITMAP_V2_ORDER CACHE_BITMAP_V2_ORDER; diff --git a/libfreerdp-cache/bitmap.c b/libfreerdp-cache/bitmap.c index 8030816ae..e733cd46b 100644 --- a/libfreerdp-cache/bitmap.c +++ b/libfreerdp-cache/bitmap.c @@ -142,7 +142,7 @@ rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmap_cache, uint32 id, uint32 inde return NULL; } - if (index == 0x7FFF) + if (index == BITMAP_CACHE_WAITING_LIST_INDEX) index = bitmap_cache->cells[id].number - 1; if (index > bitmap_cache->cells[id].number) @@ -164,7 +164,7 @@ void bitmap_cache_put(rdpBitmapCache* bitmap_cache, uint32 id, uint32 index, rdp return; } - if (index == 0x7FFF) + if (index == BITMAP_CACHE_WAITING_LIST_INDEX) index = bitmap_cache->cells[id].number - 1; if (index > bitmap_cache->cells[id].number) diff --git a/libfreerdp-codec/bitmap.c b/libfreerdp-codec/bitmap.c index 1d9a7ee2d..c0545dc54 100644 --- a/libfreerdp-codec/bitmap.c +++ b/libfreerdp-codec/bitmap.c @@ -364,32 +364,42 @@ static int process_plane(uint8* in, int width, int height, uint8* out, int size) */ static boolean bitmap_decompress4(uint8* srcData, uint8* dstData, int width, int height, int size) { + int RLE; int code; + int NoAlpha; int bytes_pro; int total_pro; - int RLE; - int NA; /* no alpha */ code = IN_UINT8_MV(srcData); RLE = code & 0x10; + if (RLE == 0) + { + /* FIXME: sometimes sent by windows 8 */ return false; + } + total_pro = 1; - NA = code & 0x20; - if (NA == 0) + NoAlpha = code & 0x20; + + if (NoAlpha == 0) { bytes_pro = process_plane(srcData, width, height, dstData + 3, size - total_pro); total_pro += bytes_pro; srcData += bytes_pro; } + bytes_pro = process_plane(srcData, width, height, dstData + 2, size - total_pro); total_pro += bytes_pro; srcData += bytes_pro; + bytes_pro = process_plane(srcData, width, height, dstData + 1, size - total_pro); total_pro += bytes_pro; srcData += bytes_pro; + bytes_pro = process_plane(srcData, width, height, dstData + 0, size - total_pro); total_pro += bytes_pro; + return (size == total_pro) ? true : false; } diff --git a/libfreerdp-core/orders.c b/libfreerdp-core/orders.c index b2cfd9843..15245c1f0 100644 --- a/libfreerdp-core/orders.c +++ b/libfreerdp-core/orders.c @@ -1241,13 +1241,18 @@ void update_read_cache_bitmap_v2_order(STREAM* s, CACHE_BITMAP_V2_ORDER* cache_b update_read_4byte_unsigned(s, &cache_bitmap_v2_order->bitmapLength); /* bitmapLength */ update_read_2byte_unsigned(s, &cache_bitmap_v2_order->cacheIndex); /* cacheIndex */ + if (cache_bitmap_v2_order->flags & CBR2_DO_NOT_CACHE) + cache_bitmap_v2_order->cacheIndex = BITMAP_CACHE_WAITING_LIST_INDEX; + if (compressed) { - if ((cache_bitmap_v2_order->flags & CBR2_NO_BITMAP_COMPRESSION_HDR) == 0) + if (!(cache_bitmap_v2_order->flags & CBR2_NO_BITMAP_COMPRESSION_HDR)) { - uint8* bitmapComprHdr = (uint8*) &cache_bitmap_v2_order->bitmapComprHdr; - stream_read(s, bitmapComprHdr, 8); /* bitmapComprHdr (8 bytes) */ - cache_bitmap_v2_order->bitmapLength -= 8; + stream_read_uint16(s, cache_bitmap_v2_order->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */ + stream_read_uint16(s, cache_bitmap_v2_order->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */ + stream_read_uint16(s, cache_bitmap_v2_order->cbScanWidth); /* cbScanWidth (2 bytes) */ + stream_read_uint16(s, cache_bitmap_v2_order->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */ + cache_bitmap_v2_order->bitmapLength = cache_bitmap_v2_order->cbCompMainBodySize; } stream_get_mark(s, cache_bitmap_v2_order->bitmapDataStream);