From d30656d4417738bbd7cfb199cf74e0176899a1cf Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 25 Nov 2013 22:26:08 -0500 Subject: [PATCH] libfreerdp-codec: start implementing uncompressed RDP6 planar codec --- include/freerdp/codec/bitmap.h | 5 + include/freerdp/codec/color.h | 14 +++ libfreerdp/codec/planar.c | 124 +++++++++++++++++++++++-- libfreerdp/codec/planar.h | 16 +++- libfreerdp/codec/test/TestFreeRDPCodecPlanar.c | 17 +--- 5 files changed, 150 insertions(+), 26 deletions(-) diff --git a/include/freerdp/codec/bitmap.h b/include/freerdp/codec/bitmap.h index c652a92..1dc7c25 100644 --- a/include/freerdp/codec/bitmap.h +++ b/include/freerdp/codec/bitmap.h @@ -23,6 +23,8 @@ #include #include +#include + #include #include @@ -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 */ diff --git a/include/freerdp/codec/color.h b/include/freerdp/codec/color.h index e73af8d..858db37 100644 --- a/include/freerdp/codec/color.h +++ b/include/freerdp/codec/color.h @@ -23,6 +23,20 @@ #include #include +#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 diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c index dc337bf..5f1dea3 100644 --- a/libfreerdp/codec/planar.c +++ b/libfreerdp/codec/planar.c @@ -21,29 +21,135 @@ #include "config.h" #endif +#include +#include + +#include + #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; +} diff --git a/libfreerdp/codec/planar.h b/libfreerdp/codec/planar.h index 665cd01..cc4a378 100644 --- a/libfreerdp/codec/planar.h +++ b/libfreerdp/codec/planar.h @@ -22,6 +22,8 @@ #include +#include + 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 */ diff --git a/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c b/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c index 3be743c..abda7e6 100644 --- a/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c +++ b/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c @@ -1,6 +1,7 @@ #include #include +#include /** * [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); -- 2.7.4