mirror of https://github.com/FreeRDP/FreeRDP
libfreerdp-codec: fix ClearCodec decoding
This commit is contained in:
parent
0e27f5abe4
commit
61eb7f2f8e
|
@ -985,45 +985,54 @@ void xf_process_channel_event(rdpChannels *channels, freerdp *instance)
|
|||
|
||||
void xf_window_free(xfContext *xfc)
|
||||
{
|
||||
rdpContext *context = (rdpContext *) xfc;
|
||||
rdpContext* context = (rdpContext*) xfc;
|
||||
|
||||
xf_keyboard_free(xfc);
|
||||
if(xfc->gc)
|
||||
|
||||
if (xfc->gc)
|
||||
{
|
||||
XFreeGC(xfc->display, xfc->gc);
|
||||
xfc->gc = 0;
|
||||
}
|
||||
if(xfc->gc_mono)
|
||||
|
||||
if (xfc->gc_mono)
|
||||
{
|
||||
XFreeGC(xfc->display, xfc->gc_mono);
|
||||
xfc->gc_mono = 0;
|
||||
}
|
||||
if(xfc->window)
|
||||
|
||||
if (xfc->window)
|
||||
{
|
||||
xf_DestroyWindow(xfc, xfc->window);
|
||||
xfc->window = NULL;
|
||||
}
|
||||
if(xfc->primary)
|
||||
|
||||
if (xfc->primary)
|
||||
{
|
||||
XFreePixmap(xfc->display, xfc->primary);
|
||||
xfc->primary = 0;
|
||||
}
|
||||
if(xfc->bitmap_mono)
|
||||
|
||||
if (xfc->bitmap_mono)
|
||||
{
|
||||
XFreePixmap(xfc->display, xfc->bitmap_mono);
|
||||
xfc->bitmap_mono = 0;
|
||||
}
|
||||
if(xfc->image)
|
||||
|
||||
if (xfc->image)
|
||||
{
|
||||
xfc->image->data = NULL;
|
||||
XDestroyImage(xfc->image);
|
||||
xfc->image = NULL;
|
||||
}
|
||||
if(context->cache)
|
||||
|
||||
if (context->cache)
|
||||
{
|
||||
cache_free(context->cache);
|
||||
context->cache = NULL;
|
||||
}
|
||||
if(context->rail)
|
||||
|
||||
if (context->rail)
|
||||
{
|
||||
rail_free(context->rail);
|
||||
context->rail = NULL;
|
||||
|
@ -1040,26 +1049,38 @@ void xf_window_free(xfContext *xfc)
|
|||
nsc_context_free(xfc->nsc);
|
||||
xfc->nsc = NULL;
|
||||
}
|
||||
if(xfc->clrconv)
|
||||
|
||||
if (xfc->clear)
|
||||
{
|
||||
clear_context_free(xfc->clear);
|
||||
xfc->clear = NULL;
|
||||
}
|
||||
|
||||
if (xfc->clrconv)
|
||||
{
|
||||
freerdp_clrconv_free(xfc->clrconv);
|
||||
xfc->clrconv = NULL;
|
||||
}
|
||||
if(xfc->hdc)
|
||||
|
||||
if (xfc->hdc)
|
||||
{
|
||||
gdi_DeleteDC(xfc->hdc);
|
||||
if(xfc->xv_context)
|
||||
}
|
||||
|
||||
if (xfc->xv_context)
|
||||
{
|
||||
xf_tsmf_uninit(xfc);
|
||||
xfc->xv_context = NULL;
|
||||
}
|
||||
if(xfc->clipboard_context)
|
||||
|
||||
if (xfc->clipboard_context)
|
||||
{
|
||||
xf_cliprdr_uninit(xfc);
|
||||
xfc->clipboard_context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void *xf_update_thread(void *arg)
|
||||
void* xf_update_thread(void *arg)
|
||||
{
|
||||
int status;
|
||||
wMessage message;
|
||||
|
|
|
@ -54,6 +54,8 @@ int xf_ResetGraphics(RdpgfxClientContext* context, RDPGFX_RESET_GRAPHICS_PDU* re
|
|||
xfc->nsc->height = resetGraphics->height;
|
||||
nsc_context_set_pixel_format(xfc->nsc, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||
|
||||
xfc->clear = clear_context_new(FALSE);
|
||||
|
||||
region16_init(&(xfc->invalidRegion));
|
||||
|
||||
xfc->graphicsReset = TRUE;
|
||||
|
@ -256,6 +258,33 @@ int xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDP
|
|||
|
||||
int xf_SurfaceCommand_ClearCodec(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
|
||||
{
|
||||
int status;
|
||||
UINT32 DstSize = 0;
|
||||
BYTE* pDstData = NULL;
|
||||
xfGfxSurface* surface;
|
||||
RECTANGLE_16 invalidRect;
|
||||
|
||||
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||
|
||||
if (!surface)
|
||||
return -1;
|
||||
|
||||
status = clear_decompress(xfc->clear, cmd->data, cmd->length, &pDstData, &DstSize);
|
||||
|
||||
printf("xf_SurfaceCommand_ClearCodec: status: %d\n", status);
|
||||
|
||||
/* fill with pink for now to distinguish from the rest */
|
||||
|
||||
freerdp_image_fill(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline,
|
||||
cmd->left, cmd->top, cmd->width, cmd->height, 0xFF69B4);
|
||||
|
||||
invalidRect.left = cmd->left;
|
||||
invalidRect.top = cmd->top;
|
||||
invalidRect.right = cmd->right;
|
||||
invalidRect.bottom = cmd->bottom;
|
||||
|
||||
region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect);
|
||||
|
||||
if (!xfc->inGfxFrame)
|
||||
xf_OutputUpdate(xfc);
|
||||
|
||||
|
@ -286,7 +315,6 @@ int xf_SurfaceCommand(RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
|
|||
break;
|
||||
|
||||
case RDPGFX_CODECID_CLEARCODEC:
|
||||
printf("xf_SurfaceCommand_ClearCodec\n");
|
||||
status = xf_SurfaceCommand_ClearCodec(xfc, context, cmd);
|
||||
break;
|
||||
|
||||
|
@ -482,8 +510,8 @@ int xf_SurfaceToCache(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_CACHE_PDU*
|
|||
|
||||
surface = (xfGfxSurface*) context->GetSurfaceData(context, surfaceToCache->surfaceId);
|
||||
|
||||
printf("xf_SurfaceToCache: cacheKey: 0x%016X cacheSlot: %ld\n",
|
||||
surfaceToCache->cacheKey, surfaceToCache->cacheSlot);
|
||||
//printf("xf_SurfaceToCache: cacheKey: 0x%016X cacheSlot: %ld\n",
|
||||
// surfaceToCache->cacheKey, surfaceToCache->cacheSlot);
|
||||
|
||||
if (!surface)
|
||||
return -1;
|
||||
|
@ -524,8 +552,8 @@ int xf_CacheToSurface(RdpgfxClientContext* context, RDPGFX_CACHE_TO_SURFACE_PDU*
|
|||
surface = (xfGfxSurface*) context->GetSurfaceData(context, cacheToSurface->surfaceId);
|
||||
cacheEntry = (xfGfxCacheEntry*) context->GetCacheSlotData(context, cacheToSurface->cacheSlot);
|
||||
|
||||
printf("xf_CacheToSurface: cacheEntry: %d\n",
|
||||
cacheToSurface->cacheSlot);
|
||||
//printf("xf_CacheToSurface: cacheEntry: %d\n",
|
||||
// cacheToSurface->cacheSlot);
|
||||
|
||||
if (!surface || !cacheEntry)
|
||||
return -1;
|
||||
|
|
|
@ -31,7 +31,7 @@ typedef struct xf_context xfContext;
|
|||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/codec/rfx.h>
|
||||
#include <freerdp/codec/nsc.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/codec/clear.h>
|
||||
#include <freerdp/codec/color.h>
|
||||
#include <freerdp/codec/bitmap.h>
|
||||
#include <freerdp/codec/region.h>
|
||||
|
@ -151,6 +151,7 @@ struct xf_context
|
|||
BYTE* bmp_codec_nsc;
|
||||
RFX_CONTEXT* rfx;
|
||||
NSC_CONTEXT* nsc;
|
||||
CLEAR_CONTEXT* clear;
|
||||
void* xv_context;
|
||||
void* clipboard_context;
|
||||
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
struct _CLEAR_CONTEXT
|
||||
{
|
||||
BOOL Compressor;
|
||||
UINT32 VBarStorageCursor;
|
||||
void* VBarStorage[32768];
|
||||
UINT32 ShortVBarStorageCursor;
|
||||
void* ShortVBarStorage[16384];
|
||||
};
|
||||
typedef struct _CLEAR_CONTEXT CLEAR_CONTEXT;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize)
|
||||
{
|
||||
int index;
|
||||
BYTE glyphFlags;
|
||||
BYTE seqNumber;
|
||||
UINT16 glyphIndex;
|
||||
|
@ -38,7 +39,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
UINT32 subcodecByteCount;
|
||||
|
||||
if (SrcSize < 2)
|
||||
return -1;
|
||||
return -1001;
|
||||
|
||||
glyphFlags = pSrcData[0];
|
||||
seqNumber = pSrcData[1];
|
||||
|
@ -49,7 +50,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
if (glyphFlags & CLEARCODEC_FLAG_GLYPH_INDEX)
|
||||
{
|
||||
if (SrcSize < 4)
|
||||
return -1;
|
||||
return -1002;
|
||||
|
||||
glyphIndex = *((UINT16*) &pSrcData[2]);
|
||||
offset += 2;
|
||||
|
@ -68,7 +69,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
/* Read composition payload header parameters */
|
||||
|
||||
if ((SrcSize - offset) < 12)
|
||||
return -1;
|
||||
return -1003;
|
||||
|
||||
residualByteCount = *((UINT32*) &pSrcData[offset]);
|
||||
bandsByteCount = *((UINT32*) &pSrcData[offset + 4]);
|
||||
|
@ -91,7 +92,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
UINT32 runLengthFactor = 0;
|
||||
|
||||
if ((SrcSize - offset) < residualByteCount)
|
||||
return -1;
|
||||
return -1004;
|
||||
|
||||
suboffset = 0;
|
||||
residualData = &pSrcData[offset];
|
||||
|
@ -99,7 +100,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
while (suboffset < residualByteCount)
|
||||
{
|
||||
if ((residualByteCount - suboffset) < 4)
|
||||
return -1;
|
||||
return -1005;
|
||||
|
||||
blueValue = residualData[suboffset];
|
||||
greenValue = residualData[suboffset + 1];
|
||||
|
@ -113,7 +114,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
if (runLengthFactor1 >= 0xFF)
|
||||
{
|
||||
if ((residualByteCount - suboffset) < 2)
|
||||
return -1;
|
||||
return -1006;
|
||||
|
||||
runLengthFactor2 = *((UINT16*) &residualData[suboffset]);
|
||||
runLengthFactor = runLengthFactor2;
|
||||
|
@ -122,7 +123,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
if (runLengthFactor2 >= 0xFFFF)
|
||||
{
|
||||
if ((residualByteCount - suboffset) < 4)
|
||||
return -1;
|
||||
return -1007;
|
||||
|
||||
runLengthFactor3 = *((UINT32*) &residualData[suboffset]);
|
||||
runLengthFactor = runLengthFactor3;
|
||||
|
@ -141,7 +142,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
UINT32 suboffset;
|
||||
|
||||
if ((SrcSize - offset) < bandsByteCount)
|
||||
return -1;
|
||||
return -1008;
|
||||
|
||||
suboffset = 0;
|
||||
bandsData = &pSrcData[offset];
|
||||
|
@ -157,9 +158,14 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
BYTE redBkg;
|
||||
BYTE* vBars;
|
||||
UINT16 vBarHeader;
|
||||
UINT16 vBarIndex;
|
||||
UINT16 vBarYOn;
|
||||
UINT16 vBarYOff;
|
||||
int vBarCount;
|
||||
int vBarPixelCount;
|
||||
|
||||
if ((bandsByteCount - suboffset) < 11)
|
||||
return -1;
|
||||
return -1009;
|
||||
|
||||
xStart = *((UINT16*) &bandsData[suboffset]);
|
||||
xEnd = *((UINT16*) &bandsData[suboffset + 2]);
|
||||
|
@ -170,31 +176,66 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
redBkg = bandsData[suboffset + 10];
|
||||
suboffset += 11;
|
||||
|
||||
vBarCount = (xEnd - xStart) + 1;
|
||||
|
||||
printf("CLEARCODEC_BAND: xStart: %d xEnd: %d yStart: %d yEnd: %d vBarCount: %d blueBkg: 0x%02X greenBkg: 0x%02X redBkg: 0x%02X\n",
|
||||
xStart, xEnd, yStart, yEnd, vBarCount, blueBkg, greenBkg, redBkg);
|
||||
|
||||
for (index = 0; index < vBarCount; index++)
|
||||
{
|
||||
vBars = &bandsData[suboffset];
|
||||
|
||||
if ((bandsByteCount - suboffset) < 2)
|
||||
return -1010;
|
||||
|
||||
vBarHeader = *((UINT16*) &vBars[0]);
|
||||
suboffset += 2;
|
||||
|
||||
if ((vBarHeader & 0xC000) == 0x8000) /* VBAR_CACHE_HIT */
|
||||
{
|
||||
printf("VBAR_CACHE_HIT\n");
|
||||
suboffset += 2;
|
||||
vBarIndex = (vBarHeader & 0x7FFF);
|
||||
|
||||
printf("VBAR_CACHE_HIT: vBarIndex: %d\n",
|
||||
vBarIndex);
|
||||
}
|
||||
else if ((vBarHeader & 0xC000) == 0xC000) /* SHORT_VBAR_CACHE_HIT */
|
||||
{
|
||||
printf("SHORT_VBAR_CACHE_HIT\n");
|
||||
suboffset += 3;
|
||||
vBarIndex = (vBarHeader & 0x3FFF);
|
||||
|
||||
if ((bandsByteCount - suboffset) < 1)
|
||||
return -1011;
|
||||
|
||||
vBarYOn = vBars[2];
|
||||
suboffset += 1;
|
||||
|
||||
printf("SHORT_VBAR_CACHE_HIT: vBarIndex: %d vBarYOn: %d\n",
|
||||
vBarIndex, vBarYOn);
|
||||
}
|
||||
else if ((vBarHeader & 0xC000) == 0) /* SHORT_VBAR_CACHE_MISS */
|
||||
else if ((vBarHeader & 0xC000) == 0x0000) /* SHORT_VBAR_CACHE_MISS */
|
||||
{
|
||||
printf("SHORT_VBAR_CACHE_MISS\n");
|
||||
suboffset += 2;
|
||||
vBarYOn = (vBarHeader & 0xFF);
|
||||
vBarYOff = ((vBarHeader >> 8) & 0x3F);
|
||||
|
||||
if (vBarYOff < vBarYOn)
|
||||
return -1012;
|
||||
|
||||
/* shortVBarPixels: variable */
|
||||
|
||||
vBarPixelCount = (3 * (vBarYOff - vBarYOn));
|
||||
|
||||
printf("SHORT_VBAR_CACHE_MISS: vBarYOn: %d vBarYOff: %d bytes: %d\n",
|
||||
vBarYOn, vBarYOff, vBarPixelCount);
|
||||
|
||||
if ((bandsByteCount - suboffset) < vBarPixelCount)
|
||||
return -1013;
|
||||
|
||||
suboffset += vBarPixelCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1; /* invalid vBarHeader */
|
||||
return -1014; /* invalid vBarHeader */
|
||||
}
|
||||
}
|
||||
|
||||
/* shortVBarPixels: variable */
|
||||
}
|
||||
|
||||
/* Decompress bands layer and write to output bitmap */
|
||||
|
@ -214,7 +255,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
UINT32 suboffset;
|
||||
|
||||
if ((SrcSize - offset) < subcodecByteCount)
|
||||
return -1;
|
||||
return -1015;
|
||||
|
||||
suboffset = 0;
|
||||
subcodecs = &pSrcData[offset];
|
||||
|
@ -222,7 +263,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
while (suboffset < subcodecByteCount)
|
||||
{
|
||||
if ((subcodecByteCount - suboffset) < 13)
|
||||
return -1;
|
||||
return -1016;
|
||||
|
||||
xStart = *((UINT16*) &subcodecs[suboffset]);
|
||||
yStart = *((UINT16*) &subcodecs[suboffset + 2]);
|
||||
|
@ -232,11 +273,11 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE*
|
|||
subcodecId = subcodecs[suboffset + 12];
|
||||
suboffset += 13;
|
||||
|
||||
printf("bitmapDataByteCount: %d subcodecByteCount: %d suboffset: %d\n",
|
||||
bitmapDataByteCount, subcodecByteCount, suboffset);
|
||||
printf("bitmapDataByteCount: %d subcodecByteCount: %d suboffset: %d subCodecId: %d\n",
|
||||
bitmapDataByteCount, subcodecByteCount, suboffset, subcodecId);
|
||||
|
||||
if ((subcodecByteCount - suboffset) < bitmapDataByteCount)
|
||||
return -1;
|
||||
return -1017;
|
||||
|
||||
bitmapData = &subcodecs[suboffset];
|
||||
|
||||
|
|
|
@ -135,9 +135,9 @@ int TestFreeRDPCodecClear(int argc, char* argv[])
|
|||
|
||||
//test_ClearDecompressExample2();
|
||||
|
||||
test_ClearDecompressExample3();
|
||||
//test_ClearDecompressExample3();
|
||||
|
||||
//test_ClearDecompressExample4();
|
||||
test_ClearDecompressExample4();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue