From 9096bd3b61374a579d4d246befc307cf36b90358 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 3 Dec 2013 18:50:22 -0500 Subject: [PATCH] libfreerdp-codec: make planar codec bitmap 01 pass the test --- libfreerdp/codec/planar.c | 107 +++++++++++++++---------- libfreerdp/codec/planar.h | 3 +- libfreerdp/codec/test/TestFreeRDPCodecPlanar.c | 84 ++++++++++++++++--- 3 files changed, 140 insertions(+), 54 deletions(-) diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c index dbcf61f..ff58ddf 100644 --- a/libfreerdp/codec/planar.c +++ b/libfreerdp/codec/planar.c @@ -320,30 +320,30 @@ struct _PLANAR_RLE_CONTEXT }; typedef struct _PLANAR_RLE_CONTEXT PLANAR_RLE_CONTEXT; -int freerdp_bitmap_planar_compress_plane_rle_segment(PLANAR_RLE_CONTEXT* rle, int position) +int freerdp_bitmap_planar_compress_plane_rle_segment(PLANAR_RLE_CONTEXT* rle) { - int k; +#if 0 + if (rle->nRunLength >= 3) + printf("### cRawBytes: %d nRunLength: %d\n", rle->cRawBytes, rle->nRunLength); - if (position < 0) - printf("B"); - else if (position == 0) - printf("M"); - else - printf("E"); + { + int k; - printf(" RAW["); + printf("RAW["); - for (k = 0; k < rle->cRawBytes; k++) - { - printf("0x%02X%s", rle->rawValues[k], - ((k + 1) == rle->cRawBytes) ? "" : ", "); - } + for (k = 0; k < rle->cRawBytes; k++) + { + printf("0x%02X%s", rle->rawValues[k], + ((k + 1) == rle->cRawBytes) ? "" : ", "); + } - printf("] RUN[%d]\n", rle->nRunLength); + printf("] RUN[%d]\n", rle->nRunLength); + } +#endif while ((rle->cRawBytes != 0) || (rle->nRunLength != 0)) { - printf("cRawBytes: %d nRunLength: %d\n", rle->cRawBytes, rle->nRunLength); + //printf("|| cRawBytes: %d nRunLength: %d\n", rle->cRawBytes, rle->nRunLength); if (rle->nRunLength < 3) { @@ -485,7 +485,6 @@ int freerdp_bitmap_planar_compress_plane_rle_segment(PLANAR_RLE_CONTEXT* rle, in CopyMemory(rle->output, rle->rawValues, rle->cRawBytes); rle->rawValues += (rle->cRawBytes + rle->nRunLength); rle->output += rle->cRawBytes; - rle->cRawBytes = 0; } rle->nRunLength -= 15; @@ -534,12 +533,11 @@ int freerdp_bitmap_planar_compress_plane_rle_segment(PLANAR_RLE_CONTEXT* rle, in BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int height, BYTE* outPlane, int* dstSize) { int i, j; - int cSegments; + int bSymbolMatch; + int bSequenceEnd; PLANAR_RLE_CONTEXT rle_s; PLANAR_RLE_CONTEXT* rle = &rle_s; - cSegments = 0; - if (!outPlane) { rle->outPlaneSize = width * height * 2; @@ -557,38 +555,69 @@ BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int hei for (i = 0; i < height; i++) { - rle->cRawBytes = 1; rle->nRunLength = 0; + rle->cRawBytes = 1; + rle->rawScanline = &inPlane[i * width]; rle->rawValues = rle->rawScanline; for (j = 1; j < width; j++) { - printf("j: %d cRawBytes: %d nRunLength: %d\n", j, rle->cRawBytes, rle->nRunLength); + bSymbolMatch = FALSE; + bSequenceEnd = ((j + 1) == width) ? TRUE : FALSE; if (rle->rawScanline[j] == rle->rawValues[rle->cRawBytes - 1]) { + bSymbolMatch = TRUE; + } + else + { + //printf("mismatch: nRunLength: %d cRawBytes: %d\n", rle->nRunLength, rle->cRawBytes); + + if (bSequenceEnd) + rle->cRawBytes++; + + if (rle->nRunLength < 3) + { + rle->cRawBytes += rle->nRunLength; + rle->nRunLength = 0; + } + else + { + bSequenceEnd = TRUE; + } + } + + if (bSymbolMatch) + { rle->nRunLength++; - continue; } - rle->cRawBytes++; + //printf("j: %d [0x%02X] cRawBytes: %d nRunLength: %d bSymbolMatch: %d bSequenceEnd: %d\n", + // j, rle->rawScanline[j], rle->cRawBytes, rle->nRunLength, bSymbolMatch, bSequenceEnd); - if (rle->nRunLength < 3) - continue; + if (bSequenceEnd) + { + if (rle->nRunLength < 3) + { + rle->cRawBytes += rle->nRunLength; + rle->nRunLength = 0; + } - if (freerdp_bitmap_planar_compress_plane_rle_segment(rle, (j == 1) ? -1 : 0) < 0) - return NULL; - } + if (freerdp_bitmap_planar_compress_plane_rle_segment(rle) < 0) + return NULL; - if (rle->nRunLength < 3) - { - rle->cRawBytes += rle->nRunLength; - rle->nRunLength = 0; + rle->nRunLength = 0; + rle->cRawBytes = 1; + } + else + { + if (!bSymbolMatch) + { + rle->cRawBytes++; + } + } } - - if (freerdp_bitmap_planar_compress_plane_rle_segment(rle, 1) < 0) - return NULL; } *dstSize = (rle->output - outPlane); @@ -613,8 +642,6 @@ int freerdp_bitmap_planar_compress_planes_rle(BYTE* inPlanes[5], int width, int #endif dstSizes[1] = outPlanesSize; - printf("PlaneR\n"); - if (!freerdp_bitmap_planar_compress_plane_rle(inPlanes[1], width, height, outPlanes, &dstSizes[1])) return 0; @@ -622,8 +649,6 @@ int freerdp_bitmap_planar_compress_planes_rle(BYTE* inPlanes[5], int width, int outPlanesSize -= dstSizes[1]; dstSizes[2] = outPlanesSize; - printf("PlaneG\n"); - if (!freerdp_bitmap_planar_compress_plane_rle(inPlanes[2], width, height, outPlanes, &dstSizes[2])) return 0; @@ -631,8 +656,6 @@ int freerdp_bitmap_planar_compress_planes_rle(BYTE* inPlanes[5], int width, int outPlanesSize -= dstSizes[2]; dstSizes[3] = outPlanesSize; - printf("PlaneB\n"); - if (!freerdp_bitmap_planar_compress_plane_rle(inPlanes[3], width, height, outPlanes, &dstSizes[3])) return 0; diff --git a/libfreerdp/codec/planar.h b/libfreerdp/codec/planar.h index b6a3466..8931f94 100644 --- a/libfreerdp/codec/planar.h +++ b/libfreerdp/codec/planar.h @@ -25,8 +25,7 @@ #include #define PLANAR_CONTROL_BYTE(_nRunLength, _cRawBytes) \ - ((_nRunLength & 0x0F) | ((_cRawBytes & 0x0F) << 4)) + \ - (printf("CONTROL_BYTE(%d, %d)\n", _cRawBytes, _nRunLength) * 0) + (_nRunLength & 0x0F) | ((_cRawBytes & 0x0F) << 4) #define PLANAR_CONTROL_BYTE_RUN_LENGTH(_controlByte) (_controlByte & 0x0F) #define PLANAR_CONTROL_BYTE_RAW_BYTES(_controlByte) ((_controlByte >> 4) & 0x0F) diff --git a/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c b/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c index 81276ea..2bb4113 100644 --- a/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c +++ b/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c @@ -10,7 +10,7 @@ * Experimental Case 01: 64x64 (32bpp) */ -const BYTE TEST_RLE_BITMAP_EXPERIMENTAL_01[16384] = +static BYTE TEST_RLE_BITMAP_EXPERIMENTAL_01[16384] = "\x1B\x1A\x16\xFF\x1C\x1A\x16\xFF\x18\x17\x13\xFF\x19\x18\x14\xFF\x17\x16\x12\xFF\x18\x16\x12\xFF\x19\x18\x14\xFF\x19\x18\x14\xFF" "\x1D\x1C\x17\xFF\x1D\x1B\x17\xFF\x1C\x1B\x17\xFF\x1B\x1A\x16\xFF\x1A\x19\x15\xFF\x1A\x19\x15\xFF\x18\x17\x13\xFF\x1A\x19\x15\xFF" "\x1B\x1A\x16\xFF\x19\x18\x14\xFF\x19\x18\x14\xFF\x18\x16\x14\xFF\x1C\x1A\x16\xFF\x1A\x18\x14\xFF\x1B\x1A\x16\xFF\x19\x17\x13\xFF" @@ -529,7 +529,7 @@ const BYTE TEST_RLE_BITMAP_EXPERIMENTAL_01[16384] = * Experimental Case 02: 64x64 (32bpp) */ -const BYTE TEST_RLE_BITMAP_EXPERIMENTAL_02[16384] = +static BYTE TEST_RLE_BITMAP_EXPERIMENTAL_02[16384] = "\x1C\x1C\x17\xFF\x1D\x1B\x18\xFF\x1B\x19\x15\xFF\x19\x18\x13\xFF\x19\x18\x14\xFF\x17\x16\x12\xFF\x17\x17\x13\xFF\x19\x17\x14\xFF" "\x15\x14\x11\xFF\x13\x13\x10\xFF\x4F\x4B\x3E\xFF\x21\x20\x1A\xFF\x22\x21\x1B\xFF\x22\x21\x1C\xFF\x22\x21\x1B\xFF\x21\x21\x1A\xFF" "\x22\x21\x1B\xFF\x21\x20\x1A\xFF\x21\x20\x1A\xFF\x21\x20\x1A\xFF\x22\x21\x1B\xFF\x23\x22\x1D\xFF\x22\x20\x1A\xFF\x21\x20\x1A\xFF" @@ -1274,6 +1274,66 @@ static void fill_bitmap_alpha_channel(BYTE* data, int width, int height, BYTE va } } +void fill_bitmap_red_channel(BYTE* data, int width, int height, BYTE value) +{ + int i, j; + UINT32* pixel; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = (UINT32*) &data[((i * width) + j) * 4]; + *pixel = ((*pixel & 0xFF00FFFF) | (value << 16)); + } + } +} + +void fill_bitmap_green_channel(BYTE* data, int width, int height, BYTE value) +{ + int i, j; + UINT32* pixel; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = (UINT32*) &data[((i * width) + j) * 4]; + *pixel = ((*pixel & 0xFFFF00FF) | (value << 8)); + } + } +} + +void fill_bitmap_blue_channel(BYTE* data, int width, int height, BYTE value) +{ + int i, j; + UINT32* pixel; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = (UINT32*) &data[((i * width) + j) * 4]; + *pixel = ((*pixel & 0xFFFFFF00) | (value)); + } + } +} + +void dump_color_channel(BYTE* data, int width, int height) +{ + int i, j; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + printf("%02X%s", *data, + ((j + 1) == width)? "\n" : " "); + data += 4; + } + } +} + int TestFreeRDPCodecPlanar(int argc, char* argv[]) { int i, j; @@ -1304,9 +1364,7 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[]) freerdp_bitmap_planar_delta_encode_plane((BYTE*) TEST_RDP6_SCANLINES_ABSOLUTE, 6, 3, NULL); freerdp_bitmap_planar_compress_plane_rle((BYTE*) TEST_RDP6_SCANLINES_DELTA_2C_ENCODED_UNSIGNED, 6, 3, NULL, &dstSize); -#endif -#if 1 for (i = 4; i < 64; i += 4) { width = i; @@ -1346,9 +1404,7 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[]) free(compressedBitmap); free(decompressedBitmap); } -#endif -#if 1 for (i = 4; i < 64; i += 4) { width = i; @@ -1457,14 +1513,17 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[]) } fill_bitmap_alpha_channel(decompressedBitmap, width, height, 0xFF); + fill_bitmap_alpha_channel((BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_01, width, height, 0xFF); if (memcmp(decompressedBitmap, (BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_01, width * height * 4) != 0) { - //printf("experimental bitmap 01\n"); - //winpr_HexDump((BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_01, width * height * 4); +#if 0 + printf("experimental bitmap 01\n"); + winpr_HexDump((BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_01, width * height * 4); - //printf("decompressed bitmap\n"); - //winpr_HexDump(decompressedBitmap, width * height * 4); + printf("decompressed bitmap\n"); + winpr_HexDump(decompressedBitmap, width * height * 4); +#endif printf("error: decompressed experimental bitmap 01 is corrupted\n"); return -1; @@ -1473,6 +1532,8 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[]) free(compressedBitmap); free(decompressedBitmap); + return 0; + /* Experimental Case 02 */ width = 64; @@ -1494,6 +1555,9 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[]) printf("success decompressing experimental bitmap 02: width: %d height: %d\n", width, height); } + fill_bitmap_alpha_channel(decompressedBitmap, width, height, 0xFF); + fill_bitmap_alpha_channel((BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_02, width, height, 0xFF); + if (memcmp(decompressedBitmap, (BYTE*) TEST_RLE_BITMAP_EXPERIMENTAL_02, width * height * 4) != 0) { printf("experimental bitmap 02\n"); -- 2.7.4