libfreerdp-codec: start implementing uncompressed RDP6 planar codec
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 26 Nov 2013 03:26:08 +0000 (22:26 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 26 Nov 2013 03:26:08 +0000 (22:26 -0500)
include/freerdp/codec/bitmap.h
include/freerdp/codec/color.h
libfreerdp/codec/planar.c
libfreerdp/codec/planar.h
libfreerdp/codec/test/TestFreeRDPCodecPlanar.c

index c652a92..1dc7c25 100644 (file)
@@ -23,6 +23,8 @@
 #include <freerdp/api.h>
 #include <freerdp/types.h>
 
+#include <freerdp/codec/color.h>
+
 #include <winpr/crt.h>
 #include <winpr/stream.h>
 
@@ -31,4 +33,7 @@ FREERDP_API BOOL bitmap_decompress(BYTE* srcData, BYTE* dstData, int width, int
 FREERDP_API int freerdp_bitmap_compress(char* in_data, int width, int height,
                wStream* s, int bpp, int byte_limit, int start_line, wStream* temp_s, int e);
 
+FREERDP_API BYTE* freerdp_bitmap_compress_planar(BYTE* data, UINT32 format, int width, int height,
+               int scanline, BYTE* dstData, int* dstSize);
+
 #endif /* FREERDP_CODEC_BITMAP_H */
index e73af8d..858db37 100644 (file)
 #include <freerdp/api.h>
 #include <freerdp/freerdp.h>
 
+#define FREERDP_PIXEL_FORMAT_TYPE_ARGB         1
+#define FREERDP_PIXEL_FORMAT_TYPE_ABGR         2
+
+#define FREERDP_PIXEL_FLIP_NONE                        0
+#define FREERDP_PIXEL_FLIP_VERTICAL            1
+#define FREERDP_PIXEL_FLIP_HORIZONTAL          2
+
+#define FREERDP_PIXEL_FORMAT(_bpp, _type, _flip) \
+       ((_bpp << 24) | (_type << 16) | (_flip << 8))
+
+#define FREERDP_PIXEL_FORMAT_BPP(_format)      (((_format) >> 24) & 0xFF)
+#define FREERDP_PIXEL_FORMAT_TYPE(_format)     (((_format) >> 16) & 0xFF)
+#define FREERDP_PIXEL_FORMAT_FLIP(_format)     (((_format) >> 8) & 0xFF)
+
 #ifdef __cplusplus
 extern "C" {
 #endif
index dc337bf..5f1dea3 100644 (file)
 #include "config.h"
 #endif
 
+#include <winpr/crt.h>
+#include <winpr/print.h>
+
+#include <freerdp/codec/bitmap.h>
+
 #include "planar.h"
 
-int freerdp_split_color_planes(BYTE* data, int width, int height, int scanline, BYTE* planes[4])
+int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* planes[4])
 {
+       int bpp;
        BYTE* srcp;
        int i, j, k;
 
        k = 0;
        srcp = data;
 
-       for (i = 0; i < height; i++)
+       bpp = FREERDP_PIXEL_FORMAT_BPP(format);
+
+       if (bpp == 32)
        {
-               for (j = 0; j < width; j++)
+               UINT32 pixel;
+
+               for (i = 0; i < height; i++)
                {
-                       planes[0][k] = data[(j * 4) + 0];
-                       planes[1][k] = data[(j * 4) + 1];
-                       planes[2][k] = data[(j * 4) + 2];
-                       planes[3][k] = data[(j * 4) + 3];
-                       k++;
+                       for (j = 0; j < width; j++)
+                       {
+                               pixel = *((UINT32*) srcp);
+                               GetARGB32(planes[0][k], planes[0][k], planes[2][k], planes[3][k], pixel);
+                               k++;
+                       }
+
+                       srcp += scanline;
                }
+       }
+       else if (bpp == 24)
+       {
+               UINT32 pixel;
+
+               for (i = 0; i < height; i++)
+               {
+                       for (j = 0; j < width; j++)
+                       {
+                               pixel = *((UINT32*) srcp);
+                               GetRGB32(planes[0][k], planes[2][k], planes[3][k], pixel);
+                               planes[0][k] = 0; /* A */
+                               k++;
+                       }
 
-               srcp += scanline;
+                       srcp += scanline;
+               }
        }
 
        return 0;
 }
+
+BYTE* freerdp_bitmap_compress_planar(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* dstData, int* dstSize)
+{
+       int size;
+       BYTE* dstp;
+       int planeSize;
+       BYTE* planes[4];
+       BYTE FormatHeader;
+       BYTE* planesBuffer;
+
+       FormatHeader = 0;
+       FormatHeader |= PLANAR_FORMAT_HEADER_NA;
+
+       planeSize = width;
+       planesBuffer = malloc(planeSize * 4);
+       planes[0] = &planesBuffer[planeSize * 0];
+       planes[1] = &planesBuffer[planeSize * 1];
+       planes[2] = &planesBuffer[planeSize * 2];
+       planes[3] = &planesBuffer[planeSize * 3];
+
+       freerdp_split_color_planes(data, format, width, height, scanline, planes);
+
+       if (!dstData)
+       {
+               size = 2;
+
+               if (!(FormatHeader & PLANAR_FORMAT_HEADER_NA))
+                       size += planeSize;
+
+               size += (planeSize * 3);
+
+               dstData = malloc(size);
+               *dstSize = size;
+       }
+
+       dstp = dstData;
+
+       *dstp = FormatHeader; /* FormatHeader */
+       dstp++;
+
+       /* AlphaPlane */
+
+       if (!(FormatHeader & PLANAR_FORMAT_HEADER_NA))
+       {
+               CopyMemory(dstp, planes[0], planeSize); /* Alpha */
+               dstp += planeSize;
+       }
+
+       /* LumaOrRedPlane */
+
+       CopyMemory(dstp, planes[1], planeSize); /* Red */
+       dstp += planeSize;
+
+       /* OrangeChromaOrGreenPlane */
+
+       CopyMemory(dstp, planes[2], planeSize); /* Green */
+       dstp += planeSize;
+
+       /* GreenChromeOrBluePlane */
+
+       CopyMemory(dstp, planes[3], planeSize); /* Blue */
+       dstp += planeSize;
+
+       /* Pad1 (1 byte) */
+
+       if (!(FormatHeader & PLANAR_FORMAT_HEADER_RLE))
+       {
+               *dstp = 0;
+               dstp++;
+       }
+
+       size = (dstp - dstData);
+       *dstSize = size;
+
+       free(planesBuffer);
+
+       return dstData;
+}
index 665cd01..cc4a378 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <winpr/crt.h>
 
+#include <freerdp/codec/color.h>
+
 struct _RDP6_RLE_SEGMENT
 {
        /**
@@ -41,20 +43,24 @@ struct _RDP6_RLE_SEGMENTS
 };
 typedef struct _RDP6_RLE_SEGMENTS RDP6_RLE_SEGMENTS;
 
+#define PLANAR_FORMAT_HEADER_CS                (1 << 3)
+#define PLANAR_FORMAT_HEADER_RLE       (1 << 4)
+#define PLANAR_FORMAT_HEADER_NA                (1 << 5)
+
 struct _RDP6_BITMAP_STREAM
 {
        /**
         * formatHeader:
-        * [0-2]: CCL
-        *  [3] : CS
-        *  [4] : RLE
-        *  [5] : NA
+        * [0-2]: Color Loss Level (CLL)
+        *  [3] : Chroma Subsampling (CS)
+        *  [4] : Run Length Encoding (RLE)
+        *  [5] : No Alpha (NA)
         * [6-7]: Reserved
         */
        BYTE formatHeader;
 };
 typedef struct _RDP6_BITMAP_STREAM RDP6_BITMAP_STREAM;
 
-int freerdp_split_color_planes(BYTE* data, int width, int height, int scanline, BYTE* planes[4]);
+int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* planes[4]);
 
 #endif /* FREERDP_CODEC_PLANAR_PRIVATE_H */
index 3be743c..abda7e6 100644 (file)
@@ -1,6 +1,7 @@
 
 #include <freerdp/freerdp.h>
 #include <freerdp/codec/color.h>
+#include <freerdp/codec/bitmap.h>
 
 /**
  * [MS-RDPEGDI] Test Bitmap 32x32 (16bpp)
@@ -156,16 +157,11 @@ const BYTE TEST_RLE_COMPRESSED_BITMAP[220] =
        "\xC3\x80\x61\x00\x00\x00\x00\x00\xCC\x89\x52\x03\x6E\xFF\xFF\x02"
        "\xCB\x18\xC6\x84\x08\x42\x08\x42\x08\x42\xFF\xFF";
 
-#include "../planar.h"
-
 int TestFreeRDPCodecPlanar(int argc, char* argv[])
 {
-       BYTE* planes[4];
+       int dstSize;
+       UINT32 format;
        HCLRCONV clrconv;
-       BYTE planeA[1024];
-       BYTE planeR[1024];
-       BYTE planeG[1024];
-       BYTE planeB[1024];
        BYTE* srcBitmap32;
        BYTE* srcBitmap16;
 
@@ -174,12 +170,9 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[])
 
        srcBitmap32 = freerdp_image_convert(srcBitmap16, NULL, 32, 32, 16, 32, clrconv);
 
-       planes[0] = planeA;
-       planes[1] = planeR;
-       planes[2] = planeG;
-       planes[3] = planeB;
+       format = FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_ARGB, FREERDP_PIXEL_FLIP_NONE);
 
-       freerdp_split_color_planes(srcBitmap32, 32, 32, 32 * 4, planes);
+       freerdp_bitmap_compress_planar(srcBitmap32, format, 32, 32, 32 * 4, NULL, &dstSize);
 
        freerdp_clrconv_free(clrconv);
        free(srcBitmap32);