From 338d809e3af952aed5f720bb802fd761485dcf08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 28 Nov 2013 19:51:29 -0500 Subject: [PATCH] libfreerdp-codec: extend planar codec unit tests --- libfreerdp/codec/planar.c | 333 +++++++++--------- .../codec/test/TestFreeRDPCodecPlanar.c | 68 +++- 2 files changed, 217 insertions(+), 184 deletions(-) diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c index ce6f1feb2..c591aa4c9 100644 --- a/libfreerdp/codec/planar.c +++ b/libfreerdp/codec/planar.c @@ -46,7 +46,7 @@ int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, for (j = 0; j < width; j++) { - GetARGB32(planes[0][k], planes[0][k], planes[2][k], planes[3][k], *pixel); + GetARGB32(planes[0][k], planes[1][k], planes[2][k], planes[3][k], *pixel); pixel++; k++; } @@ -118,12 +118,25 @@ BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int hei } } - if (nRunLength >= 3) + if (nRunLength < 3) { - printf("nRunLength: %d cRawBytes: %d\n", nRunLength, cRawBytes); + if (j != width) + { + cRawBytes++; + continue; + } + else + { + cRawBytes += nRunLength; + nRunLength = 0; + } + } -#if 1 - printf("B RAW["); + { +#if 0 + printf("scanline %d nRunLength: %d cRawBytes: %d\n", i, nRunLength, cRawBytes); + + printf("RAW["); for (k = 0; k < cRawBytes; k++) { @@ -134,6 +147,12 @@ BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int hei printf("] RUN[%d]\n", nRunLength); #endif + if ((rawValues - rawScanline) > width) + { + printf("rawValues overflow! %d\n", rawValues - rawScanline); + return NULL; + } + while (cRawBytes > 15) { nControlBytes = 1; @@ -154,139 +173,12 @@ BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int hei dstp += 15; } - if (nRunLength > 47) + if (cRawBytes == 0) { - nControlBytes = (((nRunLength - 15) + 46) / 47) + 1; - - outSegmentSize = cRawBytes + nControlBytes; - - if (((dstp - outPlane) + outSegmentSize) > outPlaneSize) - { - printf("overflow: %d > %d\n", ((dstp - outPlane) + outSegmentSize), outPlaneSize); - return NULL; - } - - *dstp = PLANAR_CONTROL_BYTE(15, cRawBytes); - nRunLength -= 15; - nControlBytes--; - dstp++; - - CopyMemory(dstp, rawValues, cRawBytes); - dstp += cRawBytes; - - while (nControlBytes--) - { - if (nRunLength > 47) - { - *dstp = PLANAR_CONTROL_BYTE(2, (47 - 32)); - nRunLength -= 47; - dstp++; - } - else if (nRunLength > 31) - { - *dstp = PLANAR_CONTROL_BYTE(2, (nRunLength - 32)); - nRunLength = 0; - dstp++; - } - else if (nRunLength > 15) - { - *dstp = PLANAR_CONTROL_BYTE(1, (nRunLength - 16)); - nRunLength = 0; - dstp++; - } - else - { - *dstp = PLANAR_CONTROL_BYTE(0, nRunLength); - nRunLength = 0; - dstp++; - } - } - } - else if (nRunLength > 31) - { - nControlBytes = 2; - outSegmentSize = cRawBytes + nControlBytes; - - if (((dstp - outPlane) + outSegmentSize) > outPlaneSize) - { - printf("overflow: %d > %d\n", ((dstp - outPlane) + outSegmentSize), outPlaneSize); - return NULL; - } - - *dstp = PLANAR_CONTROL_BYTE(15, cRawBytes); - dstp++; - - CopyMemory(dstp, rawValues, cRawBytes); - rawValues += cRawBytes; - dstp += cRawBytes; - cRawBytes = 0; - - nRunLength -= 32; - *dstp = PLANAR_CONTROL_BYTE(2, nRunLength); - dstp++; - } - else if (nRunLength > 15) - { - nControlBytes = 2; - outSegmentSize = cRawBytes + nControlBytes; - - if (((dstp - outPlane) + outSegmentSize) > outPlaneSize) - { - printf("overflow: %d > %d\n", ((dstp - outPlane) + outSegmentSize), outPlaneSize); - return NULL; - } - - *dstp = PLANAR_CONTROL_BYTE(15, cRawBytes); - dstp++; - - CopyMemory(dstp, rawValues, cRawBytes); - rawValues += cRawBytes; - dstp += cRawBytes; - cRawBytes = 0; - - nRunLength -= 16; - *dstp = PLANAR_CONTROL_BYTE(1, nRunLength); - dstp++; - } - else - { - nControlBytes = 1; - outSegmentSize = cRawBytes + nControlBytes; - - if (((dstp - outPlane) + outSegmentSize) > outPlaneSize) - { - printf("overflow: %d > %d\n", ((dstp - outPlane) + outSegmentSize), outPlaneSize); - return NULL; - } - - *dstp = PLANAR_CONTROL_BYTE(nRunLength, cRawBytes); - dstp++; - - CopyMemory(dstp, rawValues, cRawBytes); - dstp += cRawBytes; - - rawValues += (cRawBytes + nRunLength); - nRunLength = 0; - cRawBytes = 0; - - j--; - continue; - } - } - else - { - if (j != width) - { - cRawBytes++; - } - else - { - nRunLength = 0; - - while (cRawBytes > 15) + if (nRunLength > 47) { nControlBytes = 1; - outSegmentSize = 15 + nControlBytes; + outSegmentSize = nControlBytes; if (((dstp - outPlane) + outSegmentSize) > outPlaneSize) { @@ -294,42 +186,153 @@ BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int hei return NULL; } - *dstp = PLANAR_CONTROL_BYTE(0, 15); + *dstp = PLANAR_CONTROL_BYTE(2, 15); + nRunLength -= 47; dstp++; - CopyMemory(dstp, rawValues, 15); - cRawBytes -= 15; - rawValues += 15; - dstp += 15; - } - -#if 1 - printf("E RAW["); - - for (k = 0; k < cRawBytes; k++) - { - printf("0x%02X%s", rawValues[k], - ((k + 1) == cRawBytes) ? "" : ", "); - } - - printf("] RUN[%d]\n", nRunLength); -#endif - - outSegmentSize = cRawBytes + 1; - - if (((dstp - outPlane) + outSegmentSize) > outPlaneSize) - { - printf("overflow: %d > %d\n", ((dstp - outPlane) + outSegmentSize), outPlaneSize); return NULL; + + //if (j != width) + { + j--; + continue; + } } + else if (nRunLength > 31) + { + nControlBytes = 1; + outSegmentSize = nControlBytes; - *dstp = PLANAR_CONTROL_BYTE(nRunLength, cRawBytes); - dstp++; + if (((dstp - outPlane) + outSegmentSize) > outPlaneSize) + { + printf("overflow: %d > %d\n", ((dstp - outPlane) + outSegmentSize), outPlaneSize); + return NULL; + } - CopyMemory(dstp, rawValues, cRawBytes); - rawValues += cRawBytes; - dstp += cRawBytes; - cRawBytes = 0; + *dstp = PLANAR_CONTROL_BYTE(2, (nRunLength - 32)); + nRunLength -= 32; + dstp++; + + //if (j != width) + { + j--; + continue; + } + } + else if (nRunLength > 15) + { + nControlBytes = 1; + outSegmentSize = nControlBytes; + + if (((dstp - outPlane) + outSegmentSize) > outPlaneSize) + { + printf("overflow: %d > %d\n", ((dstp - outPlane) + outSegmentSize), outPlaneSize); + return NULL; + } + + *dstp = PLANAR_CONTROL_BYTE(1, (nRunLength - 16)); + nRunLength -= 16; + dstp++; + + //if (j != width) + { + j--; + continue; + } + } + else + { + nControlBytes = 1; + outSegmentSize = cRawBytes + nControlBytes; + + if (((dstp - outPlane) + outSegmentSize) > outPlaneSize) + { + printf("overflow: %d > %d\n", ((dstp - outPlane) + outSegmentSize), outPlaneSize); + return NULL; + } + + *dstp = PLANAR_CONTROL_BYTE(nRunLength, cRawBytes); + dstp++; + + CopyMemory(dstp, rawValues, cRawBytes); + rawValues += (cRawBytes + nRunLength); + dstp += cRawBytes; + cRawBytes = 0; + + nRunLength = 0; + + if (j != width) + { + j--; + continue; + } + } + } + else if (cRawBytes < 16) + { + if (nRunLength > 15) + { + nControlBytes = 2; + outSegmentSize = cRawBytes + nControlBytes; + + if (((dstp - outPlane) + outSegmentSize) > outPlaneSize) + { + printf("overflow: %d > %d\n", ((dstp - outPlane) + outSegmentSize), outPlaneSize); + return NULL; + } + + if ((!rawValues[cRawBytes - 1]) && (cRawBytes == 1)) + { + rawValues += (cRawBytes + nRunLength); + cRawBytes = 0; + } + + *dstp = PLANAR_CONTROL_BYTE(15, cRawBytes); + dstp++; + + if (cRawBytes) + { + CopyMemory(dstp, rawValues, cRawBytes); + rawValues += (cRawBytes + nRunLength); + dstp += cRawBytes; + cRawBytes = 0; + } + + nRunLength -= 15; + + { + cRawBytes = 1; + j--; + continue; + } + } + else + { + nControlBytes = 1; + outSegmentSize = cRawBytes + nControlBytes; + + if (((dstp - outPlane) + outSegmentSize) > outPlaneSize) + { + printf("overflow: %d > %d\n", ((dstp - outPlane) + outSegmentSize), outPlaneSize); + return NULL; + } + + *dstp = PLANAR_CONTROL_BYTE(nRunLength, cRawBytes); + dstp++; + + CopyMemory(dstp, rawValues, cRawBytes); + rawValues += (cRawBytes + nRunLength); + dstp += cRawBytes; + cRawBytes = 0; + + nRunLength = 0; + + if (j != width) + { + j--; + continue; + } + } } } } diff --git a/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c b/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c index 1302b4402..6af27eb98 100644 --- a/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c +++ b/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c @@ -213,9 +213,17 @@ const BYTE TEST_RDP6_SCANLINES_DELTA_2C_ENCODED_UNSIGNED[3][6] = #include "../planar.h" +static unsigned long next = 1; + +static int simple_rand(void) +{ + next = next * 1103515245 + 12345; + return ((unsigned int) (next / 65536) % 32768); +} + int TestFreeRDPCodecPlanar(int argc, char* argv[]) { - int i; + int i, j; int dstSize; UINT32 format; HCLRCONV clrconv; @@ -224,6 +232,7 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[]) int width, height; BYTE* blackBitmap; BYTE* whiteBitmap; + BYTE* randomBitmap; BYTE* compressedBitmap; BYTE* decompressedBitmap; @@ -242,16 +251,11 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[]) freerdp_bitmap_planar_compress_plane_rle((BYTE*) TEST_RDP6_SCANLINES_DELTA_2C_ENCODED_UNSIGNED, 6, 3, NULL, &dstSize); - return 0; - - for (i = 17; i < 64; i++) + for (i = 4; i < 64; i += 4) { width = i; height = i; - if ((width > 17) && (width < 65)) - continue; - whiteBitmap = (BYTE*) malloc(width * height * 4); FillMemory(whiteBitmap, width * height * 4, 0xFF); @@ -262,28 +266,23 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[]) if (!bitmap_decompress(compressedBitmap, decompressedBitmap, width, height, dstSize, 32, 32)) { - printf("failed to decompress bitmap: width: %d height: %d\n", width, height); - //return -1; + printf("failed to decompress white bitmap: width: %d height: %d\n", width, height); + return -1; } else { - printf("success decompressing bitmap: width: %d height: %d\n", width, height); + printf("success decompressing white bitmap: width: %d height: %d\n", width, height); } free(compressedBitmap); free(decompressedBitmap); } - return 0; - - for (i = 17; i < 64; i++) + for (i = 4; i < 64; i += 4) { width = i; height = i; - if ((width > 17) && (width < 65)) - continue; - blackBitmap = (BYTE*) malloc(width * height * 4); ZeroMemory(blackBitmap, width * height * 4); @@ -294,12 +293,43 @@ int TestFreeRDPCodecPlanar(int argc, char* argv[]) if (!bitmap_decompress(compressedBitmap, decompressedBitmap, width, height, dstSize, 32, 32)) { - printf("failed to decompress bitmap: width: %d height: %d\n", width, height); - //return -1; + printf("failed to decompress black bitmap: width: %d height: %d\n", width, height); + return -1; } else { - printf("success decompressing bitmap: width: %d height: %d\n", width, height); + printf("success decompressing black bitmap: width: %d height: %d\n", width, height); + } + + free(compressedBitmap); + free(decompressedBitmap); + } + + for (i = 4; i < 64; i += 4) + { + width = i; + height = i; + + randomBitmap = (BYTE*) malloc(width * height * 4); + + for (j = 0; j < width * height * 4; j++) + { + randomBitmap[j] = (BYTE) (simple_rand() % 256); + } + + compressedBitmap = freerdp_bitmap_compress_planar(randomBitmap, format, width, height, width * 4, NULL, &dstSize); + + decompressedBitmap = (BYTE*) malloc(width * height * 4); + ZeroMemory(decompressedBitmap, width * height * 4); + + if (!bitmap_decompress(compressedBitmap, decompressedBitmap, width, height, dstSize, 32, 32)) + { + printf("failed to decompress random bitmap: width: %d height: %d\n", width, height); + return -1; + } + else + { + printf("success decompressing random bitmap: width: %d height: %d\n", width, height); } free(compressedBitmap);