nsc: refactor nsc decoder #1

o the decoded argb buffer can be reused to enhance performance
o pass width, height and bpp through nsc_process_message() call
o rename nsc_context_destroy to nsc_context_free and make it actually free the context
This commit is contained in:
Vic Lee
2012-03-05 17:32:14 +08:00
parent dfb7ea3775
commit 3fa2c4830e
6 changed files with 53 additions and 28 deletions

View File

@@ -457,16 +457,14 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
}
else if (surface_bits_command->codecID == CODEC_ID_NSCODEC)
{
nsc_context->width = surface_bits_command->width;
nsc_context->height = surface_bits_command->height;
nsc_process_message(nsc_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height,
surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
wfi->image->_bitmap.width = surface_bits_command->width;
wfi->image->_bitmap.height = surface_bits_command->height;
wfi->image->_bitmap.bpp = surface_bits_command->bpp;
wfi->image->_bitmap.data = (uint8*) xrealloc(wfi->image->_bitmap.data, wfi->image->_bitmap.width * wfi->image->_bitmap.height * 4);
freerdp_image_flip(nsc_context->bmpdata, wfi->image->_bitmap.data, wfi->image->_bitmap.width, wfi->image->_bitmap.height, 32);
BitBlt(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, wfi->image->hdc, 0, 0, GDI_SRCCOPY);
nsc_context_destroy(nsc_context);
}
else if (surface_bits_command->codecID == CODEC_ID_NONE)
{

View File

@@ -928,9 +928,8 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
}
else if (surface_bits_command->codecID == CODEC_ID_NSCODEC)
{
nsc_context->width = surface_bits_command->width;
nsc_context->height = surface_bits_command->height;
nsc_process_message(nsc_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height,
surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
@@ -959,7 +958,6 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
surface_bits_command->width, surface_bits_command->height);
XSetClipMask(xfi->display, xfi->gc, None);
nsc_context_destroy(nsc_context);
}
else if (surface_bits_command->codecID == CODEC_ID_NONE)
{

View File

@@ -1003,6 +1003,12 @@ void xf_window_free(xfInfo* xfi)
xfi->rfx_context = NULL;
}
if (xfi->nsc_context)
{
nsc_context_free(xfi->nsc_context);
xfi->nsc_context = NULL;
}
freerdp_clrconv_free(xfi->clrconv);
if (xfi->hdc)

View File

@@ -46,17 +46,18 @@ struct _NSC_CONTEXT
{
uint32 OrgByteCount[4]; /* original byte length of luma, chroma orange, chroma green, alpha variable in order */
NSC_STREAM* nsc_stream;
uint16 bpp;
uint16 width;
uint16 height;
uint8* bmpdata; /* final argb values in little endian order */
uint32 bmpdata_length; /* the maximum length of the buffer that bmpdata points to */
STREAM* org_buf[4]; /* Decompressed Plane Buffers in the respective order */
};
typedef struct _NSC_CONTEXT NSC_CONTEXT;
FREERDP_API NSC_CONTEXT* nsc_context_new(void);
FREERDP_API void nsc_process_message(NSC_CONTEXT* context, uint8* data, uint32 length);
FREERDP_API void nsc_context_initialize(NSC_CONTEXT* context, STREAM* s);
FREERDP_API void nsc_stream_initialize(NSC_CONTEXT* context, STREAM* s);
FREERDP_API void nsc_process_message(NSC_CONTEXT* context, uint16 bpp,
uint16 width, uint16 height, uint8* data, uint32 length);
FREERDP_API void nsc_rle_decompress_data(NSC_CONTEXT* context);
FREERDP_API void nsc_ycocg_rgb_convert(NSC_CONTEXT* context);
FREERDP_API void nsc_rle_decode(STREAM* in, STREAM* out, uint32 origsz);
@@ -64,7 +65,7 @@ FREERDP_API void nsc_chroma_supersample(NSC_CONTEXT* context);
FREERDP_API void nsc_cl_expand(STREAM* stream, uint8 shiftcount, uint32 origsz);
FREERDP_API void nsc_colorloss_recover(NSC_CONTEXT* context);
FREERDP_API void nsc_ycocg_rgb(NSC_CONTEXT* context);
FREERDP_API void nsc_context_destroy(NSC_CONTEXT* context);
FREERDP_API void nsc_context_free(NSC_CONTEXT* context);
#ifdef __cplusplus
}

View File

@@ -289,7 +289,7 @@ void nsc_combine_argb(NSC_CONTEXT* context)
}
}
void nsc_stream_initialize(NSC_CONTEXT* context, STREAM* s)
static void nsc_stream_initialize(NSC_CONTEXT* context, STREAM* s)
{
int i;
@@ -300,16 +300,29 @@ void nsc_stream_initialize(NSC_CONTEXT* context, STREAM* s)
stream_read_uint8(s, context->nsc_stream->ChromaSubSamplingLevel);
stream_seek(s, 2);
context->nsc_stream->pdata = stream_new(0);
if (context->nsc_stream->pdata == NULL)
context->nsc_stream->pdata = stream_new(0);
stream_attach(context->nsc_stream->pdata, s->p, BYTESUM(context->nsc_stream->PlaneByteCount));
}
void nsc_context_initialize(NSC_CONTEXT* context, STREAM* s)
static void nsc_context_initialize(NSC_CONTEXT* context, STREAM* s)
{
int i;
uint32 length;
uint32 tempsz;
nsc_stream_initialize(context, s);
context->bmpdata = xzalloc(context->width * context->height * 4);
length = context->width * context->height * 4;
if (context->bmpdata == NULL)
{
context->bmpdata = xzalloc(length);
context->bmpdata_length = length;
}
else if (length > context->bmpdata_length)
{
context->bmpdata = xrealloc(context->bmpdata, length);
context->bmpdata_length = length;
}
for (i = 0; i < 4; i++)
context->OrgByteCount[i]=context->width * context->height;
@@ -336,15 +349,12 @@ void nsc_context_initialize(NSC_CONTEXT* context, STREAM* s)
}
}
void nsc_context_destroy(NSC_CONTEXT* context)
void nsc_context_free(NSC_CONTEXT* context)
{
int i;
for (i = 0;i < 4; i++)
stream_free(context->org_buf[i]);
stream_detach(context->nsc_stream->pdata);
xfree(context->bmpdata);
if (context->bmpdata)
xfree(context->bmpdata);
xfree(context);
}
NSC_CONTEXT* nsc_context_new(void)
@@ -355,11 +365,17 @@ NSC_CONTEXT* nsc_context_new(void)
return nsc_context;
}
void nsc_process_message(NSC_CONTEXT* context, uint8* data, uint32 length)
void nsc_process_message(NSC_CONTEXT* context, uint16 bpp,
uint16 width, uint16 height, uint8* data, uint32 length)
{
int i;
STREAM* s;
s = stream_new(0);
stream_attach(s, data, length);
context->bpp = bpp;
context->width = width;
context->height = height;
nsc_context_initialize(context, s);
/* RLE decode */
@@ -377,4 +393,12 @@ void nsc_process_message(NSC_CONTEXT* context, uint8* data, uint32 length)
/* Combine ARGB planes */
nsc_combine_argb(context);
for (i = 0;i < 4; i++)
{
if (context->org_buf[i])
stream_free(context->org_buf[i]);
}
stream_detach(s);
stream_free(s);
}

View File

@@ -737,9 +737,8 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co
}
else if (surface_bits_command->codecID == CODEC_ID_NSCODEC)
{
nsc_context->width = surface_bits_command->width;
nsc_context->height = surface_bits_command->height;
nsc_process_message(nsc_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height,
surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
gdi->image->bitmap->width = surface_bits_command->width;
gdi->image->bitmap->height = surface_bits_command->height;
gdi->image->bitmap->bitsPerPixel = surface_bits_command->bpp;
@@ -747,7 +746,6 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co
gdi->image->bitmap->data = (uint8*) xrealloc(gdi->image->bitmap->data, gdi->image->bitmap->width * gdi->image->bitmap->height * 4);
freerdp_image_flip(nsc_context->bmpdata, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, 32);
gdi_BitBlt(gdi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY);
nsc_context_destroy(nsc_context);
}
else if (surface_bits_command->codecID == CODEC_ID_NONE)
{