libfreerdp-codec: start implementing split NSCodec encoder
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 15 Aug 2013 03:16:13 +0000 (23:16 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 15 Aug 2013 03:16:13 +0000 (23:16 -0400)
client/Windows/wf_gdi.c
client/X11/xf_gdi.c
include/freerdp/codec/nsc.h
libfreerdp/codec/nsc.c
libfreerdp/codec/nsc_encode.c
libfreerdp/codec/nsc_sse2.c
libfreerdp/codec/nsc_types.h
libfreerdp/gdi/gdi.c
libfreerdp/gdi/graphics.c

index a11c5b1..15e9b43 100644 (file)
@@ -618,7 +618,7 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm
                bitmap_info.bmiHeader.biCompression = BI_RGB;
                SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
                        surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height,
-                       nsc_context->bmpdata, &bitmap_info, DIB_RGB_COLORS);
+                       nsc_context->BitmapData, &bitmap_info, DIB_RGB_COLORS);
                wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop,
                        surface_bits_command->width, surface_bits_command->height);
        }
index e24bdac..158c617 100644 (file)
@@ -988,7 +988,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
                xfc->bmp_codec_nsc = (BYTE*) realloc(xfc->bmp_codec_nsc,
                                surface_bits_command->width * surface_bits_command->height * 4);
 
-               freerdp_image_flip(nsc_context->bmpdata, xfc->bmp_codec_nsc,
+               freerdp_image_flip(nsc_context->BitmapData, xfc->bmp_codec_nsc,
                                surface_bits_command->width, surface_bits_command->height, 32);
 
                image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,
index 16fc580..78952d4 100644 (file)
@@ -42,9 +42,24 @@ struct _NSC_STREAM
 };
 typedef struct _NSC_STREAM NSC_STREAM;
 
+struct _NSC_MESSAGE
+{
+       int x;
+       int y;
+       UINT32 width;
+       UINT32 height;
+       BYTE* data;
+       int scanline;
+       UINT32 MaxPlaneSize;
+       UINT32 OrgByteCount[4];
+       BYTE* PlaneBuffers[4];
+};
+typedef struct _NSC_MESSAGE NSC_MESSAGE;
+
 typedef struct _NSC_CONTEXT_PRIV NSC_CONTEXT_PRIV;
 
 typedef struct _NSC_CONTEXT NSC_CONTEXT;
+
 struct _NSC_CONTEXT
 {
        UINT32 OrgByteCount[4]; /* original byte length of luma, chroma orange, chroma green, alpha variable in order */
@@ -52,15 +67,15 @@ struct _NSC_CONTEXT
        UINT16 bpp;
        UINT16 width;
        UINT16 height;
-       BYTE* bmpdata;     /* final argb values in little endian order */
-       UINT32 bmpdata_length; /* the maximum length of the buffer that bmpdata points to */
+       BYTE* BitmapData;     /* final argb values in little endian order */
+       UINT32 BitmapDataLength; /* the maximum length of the buffer that bmpdata points to */
        RDP_PIXEL_FORMAT pixel_format;
 
        /* color palette allocated by the application */
        const BYTE* palette;
 
        void (*decode)(NSC_CONTEXT* context);
-       void (*encode)(NSC_CONTEXT* context, BYTE* bmpdata, int rowstride);
+       void (*encode)(NSC_CONTEXT* context, BYTE* BitmapData, int rowstride);
 
        NSC_CONTEXT_PRIV* priv;
 };
index fe8ff32..b869b02 100644 (file)
@@ -61,7 +61,7 @@ static void nsc_decode(NSC_CONTEXT* context)
        INT16 b_val;
        BYTE* bmpdata;
 
-       bmpdata = context->bmpdata;
+       bmpdata = context->BitmapData;
        rw = ROUND_UP_TO(context->width, 8);
        shift = context->nsc_stream.ColorLossLevel - 1; /* colorloss recovery + YCoCg shift */
 
@@ -69,18 +69,18 @@ static void nsc_decode(NSC_CONTEXT* context)
        {
                if (context->nsc_stream.ChromaSubSamplingLevel > 0)
                {
-                       yplane = context->priv->plane_buf[0] + y * rw; /* Y */
-                       coplane = context->priv->plane_buf[1] + (y >> 1) * (rw >> 1); /* Co, supersampled */
-                       cgplane = context->priv->plane_buf[2] + (y >> 1) * (rw >> 1); /* Cg, supersampled */
+                       yplane = context->priv->PlaneBuffers[0] + y * rw; /* Y */
+                       coplane = context->priv->PlaneBuffers[1] + (y >> 1) * (rw >> 1); /* Co, supersampled */
+                       cgplane = context->priv->PlaneBuffers[2] + (y >> 1) * (rw >> 1); /* Cg, supersampled */
                }
                else
                {
-                       yplane = context->priv->plane_buf[0] + y * context->width; /* Y */
-                       coplane = context->priv->plane_buf[1] + y * context->width; /* Co */
-                       cgplane = context->priv->plane_buf[2] + y * context->width; /* Cg */
+                       yplane = context->priv->PlaneBuffers[0] + y * context->width; /* Y */
+                       coplane = context->priv->PlaneBuffers[1] + y * context->width; /* Co */
+                       cgplane = context->priv->PlaneBuffers[2] + y * context->width; /* Cg */
                }
 
-               aplane = context->priv->plane_buf[3] + y * context->width; /* A */
+               aplane = context->priv->PlaneBuffers[3] + y * context->width; /* A */
 
                for (x = 0; x < context->width; x++)
                {
@@ -164,11 +164,11 @@ static void nsc_rle_decompress_data(NSC_CONTEXT* context)
                planeSize = context->nsc_stream.PlaneByteCount[i];
 
                if (planeSize == 0)
-                       FillMemory(context->priv->plane_buf[i], originalSize, 0xFF);
+                       FillMemory(context->priv->PlaneBuffers[i], originalSize, 0xFF);
                else if (planeSize < originalSize)
-                       nsc_rle_decode(rle, context->priv->plane_buf[i], originalSize);
+                       nsc_rle_decode(rle, context->priv->PlaneBuffers[i], originalSize);
                else
-                       CopyMemory(context->priv->plane_buf[i], rle, originalSize);
+                       CopyMemory(context->priv->PlaneBuffers[i], rle, originalSize);
 
                rle += planeSize;
        }
@@ -198,16 +198,16 @@ static void nsc_context_initialize(NSC_CONTEXT* context, wStream* s)
        nsc_stream_initialize(context, s);
        length = context->width * context->height * 4;
 
-       if (!context->bmpdata)
+       if (!context->BitmapData)
        {
-               context->bmpdata = malloc(length + 16);
-               ZeroMemory(context->bmpdata, length + 16);
-               context->bmpdata_length = length;
+               context->BitmapData = malloc(length + 16);
+               ZeroMemory(context->BitmapData, length + 16);
+               context->BitmapDataLength = length;
        }
-       else if (length > context->bmpdata_length)
+       else if (length > context->BitmapDataLength)
        {
-               context->bmpdata = realloc(context->bmpdata, length + 16);
-               context->bmpdata_length = length;
+               context->BitmapData = realloc(context->BitmapData, length + 16);
+               context->BitmapDataLength = length;
        }
 
        tempWidth = ROUND_UP_TO(context->width, 8);
@@ -216,16 +216,18 @@ static void nsc_context_initialize(NSC_CONTEXT* context, wStream* s)
        /* The maximum length a decoded plane can reach in all cases */
        length = tempWidth * tempHeight;
 
-       if (length > context->priv->plane_buf_length)
+       if (length > context->priv->PlaneBuffersLength)
        {
                for (i = 0; i < 4; i++)
-                       context->priv->plane_buf[i] = (BYTE*) realloc(context->priv->plane_buf[i], length);
+                       context->priv->PlaneBuffers[i] = (BYTE*) realloc(context->priv->PlaneBuffers[i], length);
 
-               context->priv->plane_buf_length = length;
+               context->priv->PlaneBuffersLength = length;
        }
 
        for (i = 0; i < 4; i++)
-               context->OrgByteCount[i]=context->width * context->height;
+       {
+               context->OrgByteCount[i] = context->width * context->height;
+       }
 
        if (context->nsc_stream.ChromaSubSamplingLevel > 0)     /* [MS-RDPNSC] 2.2 */
        {
@@ -247,21 +249,58 @@ static void nsc_profiler_print(NSC_CONTEXT* context)
        PROFILER_PRINT_FOOTER;
 }
 
+NSC_CONTEXT* nsc_context_new(void)
+{
+       UINT8 i;
+       NSC_CONTEXT* context;
+
+       context = (NSC_CONTEXT*) calloc(1, sizeof(NSC_CONTEXT));
+       context->priv = (NSC_CONTEXT_PRIV*) calloc(1, sizeof(NSC_CONTEXT_PRIV));
+
+       for (i = 0; i < 5; ++i)
+       {
+               context->priv->PlaneBuffers[i] = NULL;
+       }
+
+       context->BitmapData = NULL;
+
+       context->decode = nsc_decode;
+       context->encode = nsc_encode;
+
+       context->priv->PlanePool = BufferPool_New(TRUE, 0, 16);
+
+       PROFILER_CREATE(context->priv->prof_nsc_rle_decompress_data, "nsc_rle_decompress_data");
+       PROFILER_CREATE(context->priv->prof_nsc_decode, "nsc_decode");
+       PROFILER_CREATE(context->priv->prof_nsc_rle_compress_data, "nsc_rle_compress_data");
+       PROFILER_CREATE(context->priv->prof_nsc_encode, "nsc_encode");
+
+       /* Default encoding parameters */
+       context->nsc_stream.ColorLossLevel = 3;
+       context->nsc_stream.ChromaSubSamplingLevel = 1;
+
+       /* init optimized methods */
+       NSC_INIT_SIMD(context);
+
+       return context;
+}
+
 void nsc_context_free(NSC_CONTEXT* context)
 {
        int i;
 
        for (i = 0; i < 4; i++)
        {
-               if (context->priv->plane_buf[i])
+               if (context->priv->PlaneBuffers[i])
                {
-                       free(context->priv->plane_buf[i]);
-                       context->priv->plane_buf[i] = NULL;
+                       free(context->priv->PlaneBuffers[i]);
+                       context->priv->PlaneBuffers[i] = NULL;
                }
        }
 
-       if (context->bmpdata)
-               free(context->bmpdata);
+       if (context->BitmapData)
+               free(context->BitmapData);
+
+       BufferPool_Free(context->priv->PlanePool);
 
        nsc_profiler_print(context);
        PROFILER_FREE(context->priv->prof_nsc_rle_decompress_data);
@@ -271,40 +310,6 @@ void nsc_context_free(NSC_CONTEXT* context)
 
        free(context->priv);
        free(context);
-       context = NULL;
-}
-
-NSC_CONTEXT* nsc_context_new(void)
-{
-       UINT8 i;
-       NSC_CONTEXT* nsc_context;
-
-       nsc_context = (NSC_CONTEXT*) calloc(1, sizeof(NSC_CONTEXT));
-       nsc_context->priv = (NSC_CONTEXT_PRIV*) calloc(1, sizeof(NSC_CONTEXT_PRIV));
-
-       for (i = 0; i < 5; ++i)
-       {
-               nsc_context->priv->plane_buf[i] = NULL;
-       }
-
-       nsc_context->bmpdata = NULL;
-
-       nsc_context->decode = nsc_decode;
-       nsc_context->encode = nsc_encode;
-
-       PROFILER_CREATE(nsc_context->priv->prof_nsc_rle_decompress_data, "nsc_rle_decompress_data");
-       PROFILER_CREATE(nsc_context->priv->prof_nsc_decode, "nsc_decode");
-       PROFILER_CREATE(nsc_context->priv->prof_nsc_rle_compress_data, "nsc_rle_compress_data");
-       PROFILER_CREATE(nsc_context->priv->prof_nsc_encode, "nsc_encode");
-
-       /* Default encoding parameters */
-       nsc_context->nsc_stream.ColorLossLevel = 3;
-       nsc_context->nsc_stream.ChromaSubSamplingLevel = 1;
-
-       /* init optimized methods */
-       NSC_INIT_SIMD(nsc_context);
-
-       return nsc_context;
 }
 
 void nsc_context_set_pixel_format(NSC_CONTEXT* context, RDP_PIXEL_FORMAT pixel_format)
index 9c01681..f495664 100644 (file)
@@ -48,12 +48,12 @@ static void nsc_context_initialize_encode(NSC_CONTEXT* context)
        /* The maximum length a decoded plane can reach in all cases */
        length = tempWidth * tempHeight + 16;
 
-       if (length > context->priv->plane_buf_length)
+       if (length > context->priv->PlaneBuffersLength)
        {
                for (i = 0; i < 5; i++)
-                       context->priv->plane_buf[i] = (BYTE*) realloc(context->priv->plane_buf[i], length);
+                       context->priv->PlaneBuffers[i] = (BYTE*) realloc(context->priv->PlaneBuffers[i], length);
 
-               context->priv->plane_buf_length = length;
+               context->priv->PlaneBuffersLength = length;
        }
 
        if (context->nsc_stream.ChromaSubSamplingLevel > 0)
@@ -94,18 +94,18 @@ static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* bmpdata, int r
        tempHeight = ROUND_UP_TO(context->height, 2);
        rw = (context->nsc_stream.ChromaSubSamplingLevel > 0 ? tempWidth : context->width);
        ccl = context->nsc_stream.ColorLossLevel;
-       yplane = context->priv->plane_buf[0];
-       coplane = context->priv->plane_buf[1];
-       cgplane = context->priv->plane_buf[2];
-       aplane = context->priv->plane_buf[3];
+       yplane = context->priv->PlaneBuffers[0];
+       coplane = context->priv->PlaneBuffers[1];
+       cgplane = context->priv->PlaneBuffers[2];
+       aplane = context->priv->PlaneBuffers[3];
 
        for (y = 0; y < context->height; y++)
        {
                src = bmpdata + (context->height - 1 - y) * rowstride;
-               yplane = context->priv->plane_buf[0] + y * rw;
-               coplane = context->priv->plane_buf[1] + y * rw;
-               cgplane = context->priv->plane_buf[2] + y * rw;
-               aplane = context->priv->plane_buf[3] + y * context->width;
+               yplane = context->priv->PlaneBuffers[0] + y * rw;
+               coplane = context->priv->PlaneBuffers[1] + y * rw;
+               cgplane = context->priv->PlaneBuffers[2] + y * rw;
+               aplane = context->priv->PlaneBuffers[3] + y * context->width;
 
                for (x = 0; x < context->width; x++)
                {
@@ -234,11 +234,11 @@ static void nsc_encode_subsampling(NSC_CONTEXT* context)
 
        for (y = 0; y < tempHeight >> 1; y++)
        {
-               co_dst = context->priv->plane_buf[1] + y * (tempWidth >> 1);
-               cg_dst = context->priv->plane_buf[2] + y * (tempWidth >> 1);
-               co_src0 = (INT8*) context->priv->plane_buf[1] + (y << 1) * tempWidth;
+               co_dst = context->priv->PlaneBuffers[1] + y * (tempWidth >> 1);
+               cg_dst = context->priv->PlaneBuffers[2] + y * (tempWidth >> 1);
+               co_src0 = (INT8*) context->priv->PlaneBuffers[1] + (y << 1) * tempWidth;
                co_src1 = co_src0 + tempWidth;
-               cg_src0 = (INT8*) context->priv->plane_buf[2] + (y << 1) * tempWidth;
+               cg_src0 = (INT8*) context->priv->PlaneBuffers[2] + (y << 1) * tempWidth;
                cg_src1 = cg_src0 + tempWidth;
 
                for (x = 0; x < tempWidth >> 1; x++)
@@ -338,10 +338,10 @@ static void nsc_rle_compress_data(NSC_CONTEXT* context)
                }
                else
                {
-                       planeSize = nsc_rle_encode(context->priv->plane_buf[i], context->priv->plane_buf[4], originalSize);
+                       planeSize = nsc_rle_encode(context->priv->PlaneBuffers[i], context->priv->PlaneBuffers[4], originalSize);
 
                        if (planeSize < originalSize)
-                               CopyMemory(context->priv->plane_buf[i], context->priv->plane_buf[4], planeSize);
+                               CopyMemory(context->priv->PlaneBuffers[i], context->priv->PlaneBuffers[4], planeSize);
                        else
                                planeSize = originalSize;
                }
@@ -350,7 +350,118 @@ static void nsc_rle_compress_data(NSC_CONTEXT* context)
        }
 }
 
-void nsc_compose_message(NSC_CONTEXT* context, wStream* s, BYTE* bmpdata, int width, int height, int scanline)
+UINT32 nsc_compute_byte_count(NSC_CONTEXT* context, UINT32* ByteCount, UINT32 width, UINT32 height)
+{
+       UINT32 tempWidth;
+       UINT32 tempHeight;
+       UINT32 maxPlaneSize;
+
+       tempWidth = ROUND_UP_TO(width, 8);
+       tempHeight = ROUND_UP_TO(height, 2);
+
+       maxPlaneSize = tempWidth * tempHeight + 16;
+
+       if (context->nsc_stream.ChromaSubSamplingLevel > 0)
+       {
+               ByteCount[0] = tempWidth * height;
+               ByteCount[1] = tempWidth * tempHeight / 4;
+               ByteCount[2] = tempWidth * tempHeight / 4;
+               ByteCount[3] = width * height;
+       }
+       else
+       {
+               ByteCount[0] = width * height;
+               ByteCount[1] = width * height;
+               ByteCount[2] = width * height;
+               ByteCount[3] = width * height;
+       }
+
+       return maxPlaneSize;
+}
+
+NSC_MESSAGE* nsc_encode_messages(NSC_CONTEXT* context, BYTE* data, int x, int y,
+               int width, int height, int scanline, int* numMessages, int maxDataSize)
+{
+       int step;
+       int i, j;
+       UINT32 ByteCount[4];
+       UINT32 MaxPlaneSize;
+       UINT32 MaxMessageSize;
+       NSC_MESSAGE* messages;
+
+       MaxPlaneSize = nsc_compute_byte_count(context, (UINT32*) ByteCount, width, height);
+       MaxMessageSize = MaxPlaneSize + 20;
+
+       maxDataSize -= 1024; /* reserve enough space for headers */
+
+       if (MaxMessageSize > maxDataSize)
+               *numMessages = MaxMessageSize / maxDataSize;
+
+       if (*numMessages < 1)
+               *numMessages = 1;
+
+       messages = (NSC_MESSAGE*) malloc(sizeof(NSC_MESSAGE) * (*numMessages));
+       ZeroMemory(messages, sizeof(sizeof(NSC_MESSAGE) * (*numMessages)));
+
+       if (width > height)
+       {
+               /**
+                * Horizontal Split
+                */
+
+               step = height / *numMessages;
+               step += (step % 4);
+
+               for (i = 0; i < *numMessages; i++)
+               {
+                       messages[i].x = x;
+                       messages[i].width = width;
+                       messages[i].data = data;
+                       messages[i].scanline = scanline;
+
+                       messages[i].y = y + (i * step);
+                       messages[i].height = height - (i * step);
+
+                       messages[i].MaxPlaneSize = nsc_compute_byte_count(context,
+                                       (UINT32*) messages[i].OrgByteCount, messages[i].width, messages[i].height);
+               }
+       }
+       else
+       {
+               /**
+                * Vertical Split
+                */
+
+               step = width / *numMessages;
+               step += (step % 4);
+
+               for (i = 0; i < *numMessages; i++)
+               {
+                       messages[i].y = y;
+                       messages[i].height = height;
+                       messages[i].data = data;
+                       messages[i].scanline = scanline;
+
+                       messages[i].x = x + (i * step);
+                       messages[i].width = width - (i * step);
+
+                       messages[i].MaxPlaneSize = nsc_compute_byte_count(context,
+                                       (UINT32*) messages[i].OrgByteCount, messages[i].width, messages[i].height);
+               }
+       }
+
+       for (i = 0; i < *numMessages; i++)
+       {
+               for (j = 0; j < 4; j++)
+               {
+                       messages[i].PlaneBuffers[j] = NULL;
+               }
+       }
+
+       return messages;
+}
+
+void nsc_compose_message(NSC_CONTEXT* context, wStream* s, BYTE* data, int width, int height, int scanline)
 {
        int i;
 
@@ -360,7 +471,7 @@ void nsc_compose_message(NSC_CONTEXT* context, wStream* s, BYTE* bmpdata, int wi
 
        /* ARGB to AYCoCg conversion, chroma subsampling and colorloss reduction */
        PROFILER_ENTER(context->priv->prof_nsc_encode);
-       context->encode(context, bmpdata, scanline);
+       context->encode(context, data, scanline);
        PROFILER_EXIT(context->priv->prof_nsc_encode);
 
        /* RLE encode */
@@ -383,7 +494,7 @@ void nsc_compose_message(NSC_CONTEXT* context, wStream* s, BYTE* bmpdata, int wi
                if (context->nsc_stream.PlaneByteCount[i] > 0)
                {
                        Stream_EnsureRemainingCapacity(s, (int) context->nsc_stream.PlaneByteCount[i]);
-                       Stream_Write(s, context->priv->plane_buf[i], context->nsc_stream.PlaneByteCount[i]);
+                       Stream_Write(s, context->priv->PlaneBuffers[i], context->nsc_stream.PlaneByteCount[i]);
                }
        }
 }
index f1a033f..f4f1eb1 100644 (file)
 #include <xmmintrin.h>
 #include <emmintrin.h>
 
+#include <winpr/crt.h>
+
 #include "nsc_types.h"
 #include "nsc_sse2.h"
 
-static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata, int rowstride)
+static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* data, int scanline)
 {
        UINT16 x;
        UINT16 y;
@@ -56,18 +58,19 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
        tempHeight = ROUND_UP_TO(context->height, 2);
        rw = (context->nsc_stream.ChromaSubSamplingLevel > 0 ? tempWidth : context->width);
        ccl = context->nsc_stream.ColorLossLevel;
-       yplane = context->priv->plane_buf[0];
-       coplane = context->priv->plane_buf[1];
-       cgplane = context->priv->plane_buf[2];
-       aplane = context->priv->plane_buf[3];
+       yplane = context->priv->PlaneBuffers[0];
+       coplane = context->priv->PlaneBuffers[1];
+       cgplane = context->priv->PlaneBuffers[2];
+       aplane = context->priv->PlaneBuffers[3];
 
        for (y = 0; y < context->height; y++)
        {
-               src = bmpdata + (context->height - 1 - y) * rowstride;
-               yplane = context->priv->plane_buf[0] + y * rw;
-               coplane = context->priv->plane_buf[1] + y * rw;
-               cgplane = context->priv->plane_buf[2] + y * rw;
-               aplane = context->priv->plane_buf[3] + y * context->width;
+               src = data + (context->height - 1 - y) * scanline;
+               yplane = context->priv->PlaneBuffers[0] + y * rw;
+               coplane = context->priv->PlaneBuffers[1] + y * rw;
+               cgplane = context->priv->PlaneBuffers[2] + y * rw;
+               aplane = context->priv->PlaneBuffers[3] + y * context->width;
+
                for (x = 0; x < context->width; x += 8)
                {
                        switch (context->pixel_format)
@@ -79,6 +82,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
                                        a_val = _mm_set_epi16(*(src + 31), *(src + 27), *(src + 23), *(src + 19), *(src + 15), *(src + 11), *(src + 7), *(src + 3));
                                        src += 32;
                                        break;
+
                                case RDP_PIXEL_FORMAT_R8G8B8A8:
                                        r_val = _mm_set_epi16(*(src + 28), *(src + 24), *(src + 20), *(src + 16), *(src + 12), *(src + 8), *(src + 4), *src);
                                        g_val = _mm_set_epi16(*(src + 29), *(src + 25), *(src + 21), *(src + 17), *(src + 13), *(src + 9), *(src + 5), *(src + 1));
@@ -86,6 +90,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
                                        a_val = _mm_set_epi16(*(src + 31), *(src + 27), *(src + 23), *(src + 19), *(src + 15), *(src + 11), *(src + 7), *(src + 3));
                                        src += 32;
                                        break;
+
                                case RDP_PIXEL_FORMAT_B8G8R8:
                                        b_val = _mm_set_epi16(*(src + 21), *(src + 18), *(src + 15), *(src + 12), *(src + 9), *(src + 6), *(src + 3), *src);
                                        g_val = _mm_set_epi16(*(src + 22), *(src + 19), *(src + 16), *(src + 13), *(src + 10), *(src + 7), *(src + 4), *(src + 1));
@@ -93,6 +98,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
                                        a_val = _mm_set1_epi16(0xFF);
                                        src += 24;
                                        break;
+
                                case RDP_PIXEL_FORMAT_R8G8B8:
                                        r_val = _mm_set_epi16(*(src + 21), *(src + 18), *(src + 15), *(src + 12), *(src + 9), *(src + 6), *(src + 3), *src);
                                        g_val = _mm_set_epi16(*(src + 22), *(src + 19), *(src + 16), *(src + 13), *(src + 10), *(src + 7), *(src + 4), *(src + 1));
@@ -100,6 +106,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
                                        a_val = _mm_set1_epi16(0xFF);
                                        src += 24;
                                        break;
+
                                case RDP_PIXEL_FORMAT_B5G6R5_LE:
                                        b_val = _mm_set_epi16(
                                                (((*(src + 15)) & 0xF8) | ((*(src + 15)) >> 5)),
@@ -131,6 +138,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
                                        a_val = _mm_set1_epi16(0xFF);
                                        src += 16;
                                        break;
+
                                case RDP_PIXEL_FORMAT_R5G6B5_LE:
                                        r_val = _mm_set_epi16(
                                                (((*(src + 15)) & 0xF8) | ((*(src + 15)) >> 5)),
@@ -162,6 +170,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
                                        a_val = _mm_set1_epi16(0xFF);
                                        src += 16;
                                        break;
+
                                case RDP_PIXEL_FORMAT_P4_PLANER:
                                        {
                                                int shift;
@@ -206,6 +215,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
                                        }
                                        a_val = _mm_set1_epi16(0xFF);
                                        break;
+
                                case RDP_PIXEL_FORMAT_P8:
                                        {
                                                r_val = _mm_set_epi16(
@@ -239,6 +249,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
                                        }
                                        a_val = _mm_set1_epi16(0xFF);
                                        break;
+
                                default:
                                        r_val = g_val = b_val = a_val = _mm_set1_epi16(0);
                                        break;
@@ -266,18 +277,20 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
                        cgplane += 8;
                        aplane += 8;
                }
+
                if (context->nsc_stream.ChromaSubSamplingLevel > 0 && (context->width % 2) == 1)
                {
-                       context->priv->plane_buf[0][y * rw + context->width] = context->priv->plane_buf[0][y * rw + context->width - 1];
-                       context->priv->plane_buf[1][y * rw + context->width] = context->priv->plane_buf[1][y * rw + context->width - 1];
-                       context->priv->plane_buf[2][y * rw + context->width] = context->priv->plane_buf[2][y * rw + context->width - 1];
+                       context->priv->PlaneBuffers[0][y * rw + context->width] = context->priv->PlaneBuffers[0][y * rw + context->width - 1];
+                       context->priv->PlaneBuffers[1][y * rw + context->width] = context->priv->PlaneBuffers[1][y * rw + context->width - 1];
+                       context->priv->PlaneBuffers[2][y * rw + context->width] = context->priv->PlaneBuffers[2][y * rw + context->width - 1];
                }
        }
+
        if (context->nsc_stream.ChromaSubSamplingLevel > 0 && (y % 2) == 1)
        {
-               memcpy(yplane + rw, yplane, rw);
-               memcpy(coplane + rw, coplane, rw);
-               memcpy(cgplane + rw, cgplane, rw);
+               CopyMemory(yplane + rw, yplane, rw);
+               CopyMemory(coplane + rw, coplane, rw);
+               CopyMemory(cgplane + rw, cgplane, rw);
        }
 }
 
@@ -302,12 +315,13 @@ static void nsc_encode_subsampling_sse2(NSC_CONTEXT* context)
 
        for (y = 0; y < tempHeight >> 1; y++)
        {
-               co_dst = context->priv->plane_buf[1] + y * (tempWidth >> 1);
-               cg_dst = context->priv->plane_buf[2] + y * (tempWidth >> 1);
-               co_src0 = (INT8*) context->priv->plane_buf[1] + (y << 1) * tempWidth;
+               co_dst = context->priv->PlaneBuffers[1] + y * (tempWidth >> 1);
+               cg_dst = context->priv->PlaneBuffers[2] + y * (tempWidth >> 1);
+               co_src0 = (INT8*) context->priv->PlaneBuffers[1] + (y << 1) * tempWidth;
                co_src1 = co_src0 + tempWidth;
-               cg_src0 = (INT8*) context->priv->plane_buf[2] + (y << 1) * tempWidth;
+               cg_src0 = (INT8*) context->priv->PlaneBuffers[2] + (y << 1) * tempWidth;
                cg_src1 = cg_src0 + tempWidth;
+
                for (x = 0; x < tempWidth >> 1; x += 8)
                {
                        t = _mm_loadu_si128((__m128i*) co_src0);
@@ -333,9 +347,10 @@ static void nsc_encode_subsampling_sse2(NSC_CONTEXT* context)
        }
 }
 
-static void nsc_encode_sse2(NSC_CONTEXT* context, BYTE* bmpdata, int rowstride)
+static void nsc_encode_sse2(NSC_CONTEXT* context, BYTE* data, int scanline)
 {
-       nsc_encode_argb_to_aycocg_sse2(context, bmpdata, rowstride);
+       nsc_encode_argb_to_aycocg_sse2(context, data, scanline);
+
        if (context->nsc_stream.ChromaSubSamplingLevel > 0)
        {
                nsc_encode_subsampling_sse2(context);
index 060b89d..0964167 100644 (file)
@@ -25,6 +25,9 @@
 #include "config.h"
 #endif
 
+#include <winpr/crt.h>
+#include <winpr/collections.h>
+
 #include <freerdp/utils/debug.h>
 #include <freerdp/utils/profiler.h>
 
 
 struct _NSC_CONTEXT_PRIV
 {
-       BYTE* plane_buf[5];             /* Decompressed Plane Buffers in the respective order */
-       UINT32 plane_buf_length;        /* Lengths of each plane buffer */
+       wBufferPool* PlanePool;
+
+       BYTE* PlaneBuffers[5];          /* Decompressed Plane Buffers in the respective order */
+       UINT32 PlaneBuffersLength;      /* Lengths of each plane buffer */
 
        /* profilers */
        PROFILER_DEFINE(prof_nsc_rle_decompress_data);
index d6e271d..95443ab 100644 (file)
@@ -828,7 +828,7 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co
                gdi->image->bitmap->bitsPerPixel = surface_bits_command->bpp;
                gdi->image->bitmap->bytesPerPixel = gdi->image->bitmap->bitsPerPixel / 8;
                gdi->image->bitmap->data = (BYTE*) realloc(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);
+               freerdp_image_flip(nsc_context->BitmapData, 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);
        } 
        else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE)
index 3bd5f28..2be36a5 100644 (file)
@@ -119,7 +119,7 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
                case RDP_CODEC_ID_NSCODEC:
                        gdi = context->gdi;
                        nsc_process_message(gdi->nsc_context, bpp, width, height, data, length);
-                       freerdp_image_flip(((NSC_CONTEXT*)gdi->nsc_context)->bmpdata, bitmap->data, width, height, bpp);
+                       freerdp_image_flip(((NSC_CONTEXT*)gdi->nsc_context)->BitmapData, bitmap->data, width, height, bpp);
                        break;
                case RDP_CODEC_ID_REMOTEFX:
                        gdi = context->gdi;