libfreerdp-codec: start implementing uncompressed RDP6 planar codec

This commit is contained in:
Marc-André Moreau 2013-11-25 22:26:08 -05:00
parent 7446c6f02b
commit d30656d441
5 changed files with 153 additions and 29 deletions

View 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 */

View File

@ -23,6 +23,20 @@
#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

View File

@ -21,29 +21,135 @@
#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;
bpp = FREERDP_PIXEL_FORMAT_BPP(format);
if (bpp == 32)
{
UINT32 pixel;
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
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];
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;
}
}
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;
}

View 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 */

View 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);