mirror of https://github.com/FreeRDP/FreeRDP
libfreerdp-core: move bitmap decompression out of the core
This commit is contained in:
parent
f43c9c462f
commit
24f413c0a0
|
@ -23,6 +23,7 @@
|
|||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/codec/color.h>
|
||||
#include <freerdp/codec/bitmap.h>
|
||||
|
||||
#include "xf_gdi.h"
|
||||
|
||||
|
@ -271,7 +272,7 @@ void xf_gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap)
|
|||
{
|
||||
bmp = &bitmap->bitmaps[i];
|
||||
|
||||
data = freerdp_image_convert(bmp->data, NULL, bmp->width, bmp->height, bmp->bpp, xfi->bpp, xfi->clrconv);
|
||||
data = freerdp_image_convert(bmp->dstData, NULL, bmp->width, bmp->height, bmp->bpp, xfi->bpp, xfi->clrconv);
|
||||
|
||||
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
|
||||
ZPixmap, 0, (char*) data, bmp->width, bmp->height, xfi->scanline_pad, 0);
|
||||
|
@ -895,6 +896,32 @@ void xf_gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_c
|
|||
}
|
||||
}
|
||||
|
||||
void xf_gdi_bitmap_decompress(rdpUpdate* update, BITMAP_DATA* bitmap_data)
|
||||
{
|
||||
uint16 dstSize;
|
||||
|
||||
dstSize = bitmap_data->width * bitmap_data->height * (bitmap_data->bpp / 8);
|
||||
|
||||
if (bitmap_data->dstData == NULL)
|
||||
bitmap_data->dstData = (uint8*) xmalloc(dstSize);
|
||||
else
|
||||
bitmap_data->dstData = (uint8*) xrealloc(bitmap_data->dstData, dstSize);
|
||||
|
||||
if (bitmap_data->compressed)
|
||||
{
|
||||
bitmap_decompress(bitmap_data->srcData, bitmap_data->dstData,
|
||||
bitmap_data->width, bitmap_data->height, bitmap_data->length,
|
||||
bitmap_data->bpp, bitmap_data->bpp);
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp_image_invert(bitmap_data->srcData, bitmap_data->dstData,
|
||||
bitmap_data->width, bitmap_data->height, bitmap_data->bpp);
|
||||
}
|
||||
|
||||
bitmap_data->compressed = False;
|
||||
}
|
||||
|
||||
void xf_gdi_register_update_callbacks(rdpUpdate* update)
|
||||
{
|
||||
update->Bitmap = xf_gdi_bitmap_update;
|
||||
|
@ -932,5 +959,7 @@ void xf_gdi_register_update_callbacks(rdpUpdate* update)
|
|||
update->CacheBrush = xf_gdi_cache_brush;
|
||||
|
||||
update->SurfaceBits = xf_gdi_surface_bits;
|
||||
|
||||
update->BitmapDecompress = xf_gdi_bitmap_decompress;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,12 +66,15 @@ struct _BITMAP_DATA
|
|||
uint16 bpp;
|
||||
uint16 flags;
|
||||
uint16 length;
|
||||
uint8* data;
|
||||
uint8* srcData;
|
||||
uint8* dstData;
|
||||
boolean compressed;
|
||||
};
|
||||
typedef struct _BITMAP_DATA BITMAP_DATA;
|
||||
|
||||
struct _BITMAP_UPDATE
|
||||
{
|
||||
uint16 count;
|
||||
uint16 number;
|
||||
BITMAP_DATA* bitmaps;
|
||||
};
|
||||
|
@ -1104,6 +1107,8 @@ typedef void (*pcNonMonitoredDesktop)(rdpUpdate* update, WINDOW_ORDER_INFO* orde
|
|||
typedef void (*pcSurfaceBits)(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command);
|
||||
typedef void (*pcSurfaceCommand)(rdpUpdate* update, STREAM* s);
|
||||
|
||||
typedef void (*pcBitmapDecompress)(rdpUpdate* update, BITMAP_DATA* bitmap_data);
|
||||
|
||||
struct rdp_update
|
||||
{
|
||||
void* rdp;
|
||||
|
@ -1189,6 +1194,8 @@ struct rdp_update
|
|||
pcSurfaceBits SurfaceBits;
|
||||
pcSurfaceCommand SurfaceCommand;
|
||||
|
||||
pcBitmapDecompress BitmapDecompress;
|
||||
|
||||
void* state_start;
|
||||
|
||||
BITMAP_UPDATE bitmap_update;
|
||||
|
|
|
@ -29,17 +29,6 @@ uint8 UPDATE_TYPE_STRINGS[][32] =
|
|||
"Synchronize"
|
||||
};
|
||||
|
||||
void update_free_bitmap(BITMAP_UPDATE* bitmap_update)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < bitmap_update->number; i++)
|
||||
{
|
||||
xfree(bitmap_update->bitmaps[i].data);
|
||||
}
|
||||
xfree(bitmap_update->bitmaps);
|
||||
}
|
||||
|
||||
void update_recv_orders(rdpUpdate* update, STREAM* s)
|
||||
{
|
||||
uint16 numberOrders;
|
||||
|
@ -48,8 +37,6 @@ void update_recv_orders(rdpUpdate* update, STREAM* s)
|
|||
stream_read_uint16(s, numberOrders); /* numberOrders (2 bytes) */
|
||||
stream_seek_uint16(s); /* pad2OctetsB (2 bytes) */
|
||||
|
||||
printf("numberOrders:%d\n", numberOrders);
|
||||
|
||||
while (numberOrders > 0)
|
||||
{
|
||||
update_recv_order(update, s);
|
||||
|
@ -59,9 +46,6 @@ void update_recv_orders(rdpUpdate* update, STREAM* s)
|
|||
|
||||
void update_read_bitmap_data(STREAM* s, BITMAP_DATA* bitmap_data)
|
||||
{
|
||||
uint8* srcData;
|
||||
uint16 dstSize;
|
||||
boolean status;
|
||||
uint16 bytesPerPixel;
|
||||
|
||||
stream_read_uint16(s, bitmap_data->left);
|
||||
|
@ -86,34 +70,17 @@ void update_read_bitmap_data(STREAM* s, BITMAP_DATA* bitmap_data)
|
|||
stream_seek_uint16(s); /* cbScanWidth (2 bytes) */
|
||||
stream_read_uint16(s, cbUncompressedSize); /* cbUncompressedSize (2 bytes) */
|
||||
|
||||
dstSize = cbUncompressedSize;
|
||||
bitmap_data->length = cbCompMainBodySize;
|
||||
bitmap_data->data = (uint8*) xmalloc(dstSize);
|
||||
|
||||
stream_get_mark(s, srcData);
|
||||
bitmap_data->compressed = True;
|
||||
stream_get_mark(s, bitmap_data->srcData);
|
||||
stream_seek(s, bitmap_data->length);
|
||||
|
||||
status = bitmap_decompress(srcData, bitmap_data->data, bitmap_data->width, bitmap_data->height,
|
||||
bitmap_data->length, bitmap_data->bpp, bitmap_data->bpp);
|
||||
|
||||
if (status != True)
|
||||
printf("bitmap decompression failed, bpp:%d\n", bitmap_data->bpp);
|
||||
}
|
||||
else
|
||||
{
|
||||
int y;
|
||||
int offset;
|
||||
int scanline;
|
||||
stream_get_mark(s, srcData);
|
||||
dstSize = bitmap_data->length;
|
||||
bitmap_data->data = (uint8*) xzalloc(dstSize);
|
||||
scanline = bitmap_data->width * (bitmap_data->bpp / 8);
|
||||
|
||||
for (y = 0; y < bitmap_data->height; y++)
|
||||
{
|
||||
offset = (bitmap_data->height - y - 1) * scanline;
|
||||
stream_read(s, &bitmap_data->data[offset], scanline);
|
||||
}
|
||||
bitmap_data->compressed = False;
|
||||
stream_get_mark(s, bitmap_data->srcData);
|
||||
stream_seek(s, bitmap_data->length);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,15 +88,28 @@ void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_upda
|
|||
{
|
||||
int i;
|
||||
|
||||
update_free_bitmap(bitmap_update);
|
||||
stream_read_uint16(s, bitmap_update->number); /* numberRectangles (2 bytes) */
|
||||
|
||||
bitmap_update->bitmaps = (BITMAP_DATA*) xzalloc(sizeof(BITMAP_DATA) * bitmap_update->number);
|
||||
if (bitmap_update->number > bitmap_update->count)
|
||||
{
|
||||
uint16 count;
|
||||
|
||||
count = bitmap_update->number * 2;
|
||||
|
||||
bitmap_update->bitmaps = (BITMAP_DATA*) xrealloc(bitmap_update->bitmaps,
|
||||
sizeof(BITMAP_DATA) * count);
|
||||
|
||||
memset(&bitmap_update->bitmaps[bitmap_update->count], 0,
|
||||
sizeof(BITMAP_DATA) * (count - bitmap_update->count));
|
||||
|
||||
bitmap_update->count = count;
|
||||
}
|
||||
|
||||
/* rectangles */
|
||||
for (i = 0; i < bitmap_update->number; i++)
|
||||
{
|
||||
update_read_bitmap_data(s, &bitmap_update->bitmaps[i]);
|
||||
IFCALL(update->BitmapDecompress, update, &bitmap_update->bitmaps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -325,6 +305,11 @@ void update_recv(rdpUpdate* update, STREAM* s)
|
|||
void update_reset_state(rdpUpdate* update)
|
||||
{
|
||||
int length;
|
||||
uint16 bitmap_count;
|
||||
BITMAP_DATA* bitmaps;
|
||||
|
||||
bitmaps = update->bitmap_update.bitmaps;
|
||||
bitmap_count = update->bitmap_update.count;
|
||||
|
||||
length = &update->state_end - &update->state_start;
|
||||
|
||||
|
@ -332,6 +317,9 @@ void update_reset_state(rdpUpdate* update)
|
|||
update->order_info.orderType = ORDER_TYPE_PATBLT;
|
||||
update->switch_surface.bitmapId = SCREEN_BITMAP_SURFACE;
|
||||
IFCALL(update->SwitchSurface, update, &(update->switch_surface));
|
||||
|
||||
update->bitmap_update.bitmaps = bitmaps;
|
||||
update->bitmap_update.count = bitmap_count;
|
||||
}
|
||||
|
||||
static void update_begin_paint(rdpUpdate* update)
|
||||
|
@ -408,6 +396,9 @@ rdpUpdate* update_new(rdpRdp* rdp)
|
|||
if (update != NULL)
|
||||
{
|
||||
update->rdp = (void*) rdp;
|
||||
|
||||
update->bitmap_update.count = 64;
|
||||
update->bitmap_update.bitmaps = (BITMAP_DATA*) xzalloc(sizeof(BITMAP_DATA) * update->bitmap_update.count);
|
||||
}
|
||||
|
||||
return update;
|
||||
|
@ -415,10 +406,21 @@ rdpUpdate* update_new(rdpRdp* rdp)
|
|||
|
||||
void update_free(rdpUpdate* update)
|
||||
{
|
||||
update_free_bitmap(&update->bitmap_update);
|
||||
|
||||
if (update != NULL)
|
||||
{
|
||||
uint16 i;
|
||||
BITMAP_DATA* bitmaps;
|
||||
BITMAP_UPDATE* bitmap_update;
|
||||
|
||||
bitmap_update = &update->bitmap_update;
|
||||
bitmaps = update->bitmap_update.bitmaps;
|
||||
|
||||
for (i = 0; i < bitmap_update->count; i++)
|
||||
{
|
||||
if (bitmaps[i].dstData != NULL)
|
||||
xfree(bitmaps[i].dstData);
|
||||
}
|
||||
|
||||
xfree(update);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/bitmap.h>
|
||||
#include <freerdp/codec/color.h>
|
||||
#include <freerdp/codec/bitmap.h>
|
||||
#include <freerdp/codec/rfx.h>
|
||||
#include <freerdp/codec/nsc.h>
|
||||
|
||||
|
@ -452,7 +453,7 @@ void gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap)
|
|||
{
|
||||
bmp = &bitmap->bitmaps[i];
|
||||
|
||||
gdi_bmp = gdi_bitmap_new(gdi, bmp->width, bmp->height, gdi->dstBpp, bmp->data);
|
||||
gdi_bmp = gdi_bitmap_new(gdi, bmp->width, bmp->height, gdi->dstBpp, bmp->dstData);
|
||||
|
||||
gdi_BitBlt(gdi->primary->hdc,
|
||||
bmp->left, bmp->top, bmp->right - bmp->left + 1,
|
||||
|
@ -944,6 +945,32 @@ void gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_comm
|
|||
xfree(tile_bitmap);
|
||||
}
|
||||
|
||||
void gdi_bitmap_decompress(rdpUpdate* update, BITMAP_DATA* bitmap_data)
|
||||
{
|
||||
uint16 dstSize;
|
||||
|
||||
dstSize = bitmap_data->width * bitmap_data->height * (bitmap_data->bpp / 8);
|
||||
|
||||
if (bitmap_data->dstData == NULL)
|
||||
bitmap_data->dstData = (uint8*) xmalloc(dstSize);
|
||||
else
|
||||
bitmap_data->dstData = (uint8*) xrealloc(bitmap_data->dstData, dstSize);
|
||||
|
||||
if (bitmap_data->compressed)
|
||||
{
|
||||
bitmap_decompress(bitmap_data->srcData, bitmap_data->dstData,
|
||||
bitmap_data->width, bitmap_data->height, bitmap_data->length,
|
||||
bitmap_data->bpp, bitmap_data->bpp);
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp_image_invert(bitmap_data->srcData, bitmap_data->dstData,
|
||||
bitmap_data->width, bitmap_data->height, bitmap_data->bpp);
|
||||
}
|
||||
|
||||
bitmap_data->compressed = False;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register GDI callbacks with libfreerdp-core.
|
||||
* @param inst current instance
|
||||
|
@ -987,6 +1014,7 @@ void gdi_register_update_callbacks(rdpUpdate* update)
|
|||
update->CacheBrush = gdi_cache_brush;
|
||||
|
||||
update->SurfaceBits = gdi_surface_bits;
|
||||
update->BitmapDecompress = gdi_bitmap_decompress;
|
||||
}
|
||||
|
||||
void gdi_init_primary(GDI* gdi)
|
||||
|
|
Loading…
Reference in New Issue