return (size == (srcp - srcData)) ? 0 : -1;
}
-int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* planes[5])
+int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* planes[4])
{
int bpp;
int i, j, k;
return outPlane;
}
-int freerdp_bitmap_planar_compress_planes_rle(BYTE* inPlanes[5], int width, int height, BYTE* outPlanes, int* dstSizes)
+int freerdp_bitmap_planar_compress_planes_rle(BYTE* inPlanes[4], int width, int height, BYTE* outPlanes, int* dstSizes)
{
int outPlanesSize = width * height * 4;
return outPlane;
}
-int freerdp_bitmap_planar_delta_encode_planes(BYTE* inPlanes[5], int width, int height, BYTE* outPlanes[5])
+int freerdp_bitmap_planar_delta_encode_planes(BYTE* inPlanes[4], int width, int height, BYTE* outPlanes[4])
{
freerdp_bitmap_planar_delta_encode_plane(inPlanes[0], width, height, outPlanes[0]);
freerdp_bitmap_planar_delta_encode_plane(inPlanes[1], width, height, outPlanes[1]);
return 0;
}
-//static int g_Count = 0;
-
-BYTE* freerdp_bitmap_compress_planar(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* dstData, int* dstSize)
+BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, BYTE* data, UINT32 format,
+ int width, int height, int scanline, BYTE* dstData, int* dstSize)
{
int size;
BYTE* dstp;
int planeSize;
int dstSizes[4];
- BYTE* planes[5];
- BYTE* planesBuffer;
- BYTE* deltaPlanes[5];
- BYTE* deltaPlanesBuffer;
- BYTE* rlePlanes[4];
- BYTE* rlePlanesBuffer;
BYTE FormatHeader = 0;
- FormatHeader |= PLANAR_FORMAT_HEADER_NA;
+ if (context->AllowSkipAlpha)
+ FormatHeader |= PLANAR_FORMAT_HEADER_NA;
planeSize = width * height;
- planesBuffer = malloc(planeSize * 5);
- planes[0] = &planesBuffer[planeSize * 0];
- planes[1] = &planesBuffer[planeSize * 1];
- planes[2] = &planesBuffer[planeSize * 2];
- planes[3] = &planesBuffer[planeSize * 3];
- planes[4] = &planesBuffer[planeSize * 4];
-
- deltaPlanesBuffer = malloc(planeSize * 5);
- deltaPlanes[0] = &deltaPlanesBuffer[planeSize * 0];
- deltaPlanes[1] = &deltaPlanesBuffer[planeSize * 1];
- deltaPlanes[2] = &deltaPlanesBuffer[planeSize * 2];
- deltaPlanes[3] = &deltaPlanesBuffer[planeSize * 3];
- deltaPlanes[4] = &deltaPlanesBuffer[planeSize * 4];
-
- rlePlanesBuffer = malloc(planeSize * 4);
-
- freerdp_split_color_planes(data, format, width, height, scanline, planes);
-
- freerdp_bitmap_planar_delta_encode_planes(planes, width, height, deltaPlanes);
+ freerdp_split_color_planes(data, format, width, height, scanline, context->planes);
-#if 0
+ if (context->AllowRunLengthEncoding)
{
- g_Count++;
- BYTE* bitmap;
- int bitmapLength;
-
- bitmapLength = width * height * 4;
- bitmap = malloc(width * height * 4);
- ZeroMemory(bitmap, bitmapLength);
-
- freerdp_bitmap_planar_decompress_plane_raw(planes[0], width, height, bitmap + 3, planeSize); /* A */
- freerdp_bitmap_planar_decompress_plane_raw(planes[1], width, height, bitmap + 2, planeSize); /* R */
- freerdp_bitmap_planar_decompress_plane_raw(planes[2], width, height, bitmap + 1, planeSize); /* G */
- freerdp_bitmap_planar_decompress_plane_raw(planes[3], width, height, bitmap + 0, planeSize); /* B */
+ freerdp_bitmap_planar_delta_encode_planes(context->planes, width, height, context->deltaPlanes);
- printf("Bitmap %02d\n", g_Count);
- winpr_CArrayDump(bitmap, bitmapLength, 32);
-
- free(bitmap);
- }
-#endif
-
- if (freerdp_bitmap_planar_compress_planes_rle(deltaPlanes, width, height, rlePlanesBuffer, (int*) &dstSizes) > 0)
- {
- int offset = 0;
+ if (freerdp_bitmap_planar_compress_planes_rle(context->deltaPlanes, width, height, context->rlePlanesBuffer, (int*) &dstSizes) > 0)
+ {
+ int offset = 0;
- FormatHeader |= PLANAR_FORMAT_HEADER_RLE;
+ FormatHeader |= PLANAR_FORMAT_HEADER_RLE;
- rlePlanes[0] = &rlePlanesBuffer[offset];
- offset += dstSizes[0];
+ context->rlePlanes[0] = &context->rlePlanesBuffer[offset];
+ offset += dstSizes[0];
- rlePlanes[1] = &rlePlanesBuffer[offset];
- offset += dstSizes[1];
+ context->rlePlanes[1] = &context->rlePlanesBuffer[offset];
+ offset += dstSizes[1];
- rlePlanes[2] = &rlePlanesBuffer[offset];
- offset += dstSizes[2];
+ context->rlePlanes[2] = &context->rlePlanesBuffer[offset];
+ offset += dstSizes[2];
- rlePlanes[3] = &rlePlanesBuffer[offset];
- offset += dstSizes[3];
+ context->rlePlanes[3] = &context->rlePlanesBuffer[offset];
+ offset += dstSizes[3];
- printf("R: [%d/%d] G: [%d/%d] B: [%d/%d]\n",
- dstSizes[1], planeSize, dstSizes[2], planeSize, dstSizes[3], planeSize);
+ printf("R: [%d/%d] G: [%d/%d] B: [%d/%d]\n",
+ dstSizes[1], planeSize, dstSizes[2], planeSize, dstSizes[3], planeSize);
+ }
}
if (!dstData)
{
if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
{
- CopyMemory(dstp, rlePlanes[0], dstSizes[0]); /* Alpha */
+ CopyMemory(dstp, context->rlePlanes[0], dstSizes[0]); /* Alpha */
dstp += dstSizes[0];
}
else
{
- CopyMemory(dstp, planes[0], planeSize); /* Alpha */
+ CopyMemory(dstp, context->planes[0], planeSize); /* Alpha */
dstp += planeSize;
}
}
if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
{
- CopyMemory(dstp, rlePlanes[1], dstSizes[1]); /* Red */
+ CopyMemory(dstp, context->rlePlanes[1], dstSizes[1]); /* Red */
dstp += dstSizes[1];
}
else
{
- CopyMemory(dstp, planes[1], planeSize); /* Red */
+ CopyMemory(dstp, context->planes[1], planeSize); /* Red */
dstp += planeSize;
}
if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
{
- CopyMemory(dstp, rlePlanes[2], dstSizes[2]); /* Green */
+ CopyMemory(dstp, context->rlePlanes[2], dstSizes[2]); /* Green */
dstp += dstSizes[2];
}
else
{
- CopyMemory(dstp, planes[2], planeSize); /* Green */
+ CopyMemory(dstp, context->planes[2], planeSize); /* Green */
dstp += planeSize;
}
if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
{
- CopyMemory(dstp, rlePlanes[3], dstSizes[3]); /* Blue */
+ CopyMemory(dstp, context->rlePlanes[3], dstSizes[3]); /* Blue */
dstp += dstSizes[3];
}
else
{
- CopyMemory(dstp, planes[3], planeSize); /* Blue */
+ CopyMemory(dstp, context->planes[3], planeSize); /* Blue */
dstp += planeSize;
}
size = (dstp - dstData);
*dstSize = size;
- free(rlePlanesBuffer);
- free(deltaPlanesBuffer);
- free(planesBuffer);
-
return dstData;
}
+
+BITMAP_PLANAR_CONTEXT* freerdp_bitmap_planar_context_new(DWORD flags, int maxWidth, int maxHeight)
+{
+ BITMAP_PLANAR_CONTEXT* context;
+
+ context = (BITMAP_PLANAR_CONTEXT*) malloc(sizeof(BITMAP_PLANAR_CONTEXT));
+
+ if (!context)
+ return NULL;
+
+ ZeroMemory(context, sizeof(BITMAP_PLANAR_CONTEXT));
+
+ if (flags & PLANAR_FORMAT_HEADER_NA)
+ context->AllowSkipAlpha = TRUE;
+
+ if (flags & PLANAR_FORMAT_HEADER_RLE)
+ context->AllowRunLengthEncoding = TRUE;
+
+ if (flags & PLANAR_FORMAT_HEADER_CS)
+ context->AllowColorSubsampling = TRUE;
+
+ context->ColorLossLevel = flags & PLANAR_FORMAT_HEADER_CLL_MASK;
+
+ if (context->ColorLossLevel)
+ context->AllowDynamicColorFidelity = TRUE;
+
+ context->maxWidth = maxWidth;
+ context->maxHeight = maxHeight;
+ context->maxPlaneSize = context->maxWidth * context->maxHeight;
+
+ context->planesBuffer = malloc(context->maxPlaneSize * 4);
+ context->planes[0] = &context->planesBuffer[context->maxPlaneSize * 0];
+ context->planes[1] = &context->planesBuffer[context->maxPlaneSize * 1];
+ context->planes[2] = &context->planesBuffer[context->maxPlaneSize * 2];
+ context->planes[3] = &context->planesBuffer[context->maxPlaneSize * 3];
+
+ context->deltaPlanesBuffer = malloc(context->maxPlaneSize * 4);
+ context->deltaPlanes[0] = &context->deltaPlanesBuffer[context->maxPlaneSize * 0];
+ context->deltaPlanes[1] = &context->deltaPlanesBuffer[context->maxPlaneSize * 1];
+ context->deltaPlanes[2] = &context->deltaPlanesBuffer[context->maxPlaneSize * 2];
+ context->deltaPlanes[3] = &context->deltaPlanesBuffer[context->maxPlaneSize * 3];
+
+ context->rlePlanesBuffer = malloc(context->maxPlaneSize * 4);
+
+ return context;
+}
+
+void freerdp_bitmap_planar_context_free(BITMAP_PLANAR_CONTEXT* context)
+{
+ if (!context)
+ return;
+
+ free(context->planesBuffer);
+ free(context->deltaPlanesBuffer);
+ free(context->rlePlanesBuffer);
+
+ free(context);
+}
#include <winpr/crt.h>
#include <freerdp/codec/color.h>
+#include <freerdp/codec/bitmap.h>
#define PLANAR_CONTROL_BYTE(_nRunLength, _cRawBytes) \
(_nRunLength & 0x0F) | ((_cRawBytes & 0x0F) << 4)
};
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
{
/**
};
typedef struct _RDP6_BITMAP_STREAM RDP6_BITMAP_STREAM;
+struct _BITMAP_PLANAR_CONTEXT
+{
+ int maxWidth;
+ int maxHeight;
+ int maxPlaneSize;
+
+ BOOL AllowSkipAlpha;
+ BOOL AllowRunLengthEncoding;
+ BOOL AllowColorSubsampling;
+ BOOL AllowDynamicColorFidelity;
+
+ int ColorLossLevel;
+
+ BYTE* planes[4];
+ BYTE* planesBuffer;
+
+ BYTE* deltaPlanes[4];
+ BYTE* deltaPlanesBuffer;
+
+ BYTE* rlePlanes[4];
+ BYTE* rlePlanesBuffer;
+};
+
int freerdp_bitmap_planar_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int size);
-int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* planes[5]);
+int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* planes[4]);
BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* plane, int width, int height, BYTE* outPlane, int* dstSize);
BYTE* freerdp_bitmap_planar_delta_encode_plane(BYTE* inPlane, int width, int height, BYTE* outPlane);
-int freerdp_bitmap_planar_delta_encode_planes(BYTE* inPlanes[5], int width, int height, BYTE* outPlanes[5]);
+int freerdp_bitmap_planar_delta_encode_planes(BYTE* inPlanes[4], int width, int height, BYTE* outPlanes[4]);
#endif /* FREERDP_CODEC_PLANAR_PRIVATE_H */
int dstSize;
UINT32 format;
HCLRCONV clrconv;
+ DWORD planarFlags;
BYTE* srcBitmap32;
BYTE* srcBitmap16;
int width, height;
BYTE* randomBitmap;
BYTE* compressedBitmap;
BYTE* decompressedBitmap;
+ BITMAP_PLANAR_CONTEXT* planar;
+
+ planarFlags = PLANAR_FORMAT_HEADER_NA;
+ //planarFlags |= PLANAR_FORMAT_HEADER_RLE;
+
+ planar = freerdp_bitmap_planar_context_new(planarFlags, 64, 64);
clrconv = freerdp_clrconv_new(0);
srcBitmap16 = (BYTE*) TEST_RLE_UNCOMPRESSED_BITMAP_16BPP;
format = FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_ARGB, FREERDP_PIXEL_FLIP_NONE);
-#if 0
- freerdp_bitmap_compress_planar(srcBitmap32, format, 32, 32, 32 * 4, NULL, &dstSize);
+#if 1
+ freerdp_bitmap_compress_planar(planar, srcBitmap32, format, 32, 32, 32 * 4, NULL, &dstSize);
freerdp_bitmap_planar_compress_plane_rle((BYTE*) TEST_RLE_SCANLINE_UNCOMPRESSED, 12, 1, NULL, &dstSize);
FillMemory(whiteBitmap, width * height * 4, 0xFF);
fill_bitmap_alpha_channel(whiteBitmap, width, height, 0x00);
- compressedBitmap = freerdp_bitmap_compress_planar(whiteBitmap, format, width, height, width * 4, NULL, &dstSize);
+ compressedBitmap = freerdp_bitmap_compress_planar(planar, whiteBitmap, format, width, height, width * 4, NULL, &dstSize);
decompressedBitmap = (BYTE*) malloc(width * height * 4);
ZeroMemory(decompressedBitmap, width * height * 4);
ZeroMemory(blackBitmap, width * height * 4);
fill_bitmap_alpha_channel(blackBitmap, width, height, 0x00);
- compressedBitmap = freerdp_bitmap_compress_planar(blackBitmap, format, width, height, width * 4, NULL, &dstSize);
+ compressedBitmap = freerdp_bitmap_compress_planar(planar, blackBitmap, format, width, height, width * 4, NULL, &dstSize);
decompressedBitmap = (BYTE*) malloc(width * height * 4);
ZeroMemory(decompressedBitmap, width * height * 4);
fill_bitmap_alpha_channel(randomBitmap, width, height, 0x00);
- compressedBitmap = freerdp_bitmap_compress_planar(randomBitmap, format, width, height, width * 4, NULL, &dstSize);
+ compressedBitmap = freerdp_bitmap_compress_planar(planar, randomBitmap, format, width, height, width * 4, NULL, &dstSize);
decompressedBitmap = (BYTE*) malloc(width * height * 4);
ZeroMemory(decompressedBitmap, width * height * 4);
}
#endif
-#if 0
+#if 1
/* Experimental Case 01 */
width = 64;
height = 64;
- compressedBitmap = freerdp_bitmap_compress_planar((BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_01,
+ compressedBitmap = freerdp_bitmap_compress_planar(planar, (BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_01,
format, width, height, width * 4, NULL, &dstSize);
decompressedBitmap = (BYTE*) malloc(width * height * 4);
free(decompressedBitmap);
#endif
-#if 0
+#if 1
/* Experimental Case 02 */
width = 64;
height = 64;
- compressedBitmap = freerdp_bitmap_compress_planar((BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_02,
+ compressedBitmap = freerdp_bitmap_compress_planar(planar, (BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_02,
format, width, height, width * 4, NULL, &dstSize);
decompressedBitmap = (BYTE*) malloc(width * height * 4);
width = 64;
height = 64;
- compressedBitmap = freerdp_bitmap_compress_planar((BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_03,
+ compressedBitmap = freerdp_bitmap_compress_planar(planar, (BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_03,
format, width, height, width * 4, NULL, &dstSize);
decompressedBitmap = (BYTE*) malloc(width * height * 4);
freerdp_clrconv_free(clrconv);
free(srcBitmap32);
+ freerdp_bitmap_planar_context_free(planar);
+
return 0;
}