libfreerdp-codec: reorganize planar RLE encoding logic
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 28 Nov 2013 20:49:22 +0000 (15:49 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 28 Nov 2013 20:49:22 +0000 (15:49 -0500)
libfreerdp/codec/planar.c
libfreerdp/codec/test/TestFreeRDPCodecPlanar.c

index c685594..ce6f1fe 100644 (file)
@@ -75,13 +75,13 @@ int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height,
 
 BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int height, BYTE* outPlane, int* dstSize)
 {
-       int i, j;
+       int i, j, k;
        BYTE* dstp;
-       BYTE symbol;
        int cSegments;
        int nRunLength;
        int cRawBytes;
        BYTE* rawValues;
+       BYTE* rawScanline;
        int outPlaneSize;
        int outSegmentSize;
        int nControlBytes;
@@ -102,31 +102,28 @@ BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int hei
 
        for (i = 0; i < height; i++)
        {
-               cRawBytes = 0;
-               nRunLength = -1;
-               rawValues = &inPlane[i * width];
+               cRawBytes = 1;
+               nRunLength = 0;
+               rawScanline = &inPlane[i * width];
+               rawValues = rawScanline;
 
-               for (j = 0; j <= width; j++)
+               for (j = 1; j <= width; j++)
                {
-                       if ((nRunLength < 0) && (j != width))
-                       {
-                               symbol = inPlane[(i * width) + j];
-                               nRunLength = 0;
-                               continue;
-                       }
-
-                       if ((j != width) && (inPlane[(i * width) + j] == symbol))
+                       if (j != width)
                        {
-                               nRunLength++;
-                               continue;
+                               if (rawScanline[j] == rawValues[cRawBytes - 1])
+                               {
+                                       nRunLength++;
+                                       continue;
+                               }
                        }
 
                        if (nRunLength >= 3)
                        {
-                               cRawBytes += 1;
+                               printf("nRunLength: %d cRawBytes: %d\n", nRunLength, cRawBytes);
 
-#if 0
-                               printf("RAW[");
+#if 1
+                               printf("RAW[");
 
                                for (k = 0; k < cRawBytes; k++)
                                {
@@ -204,8 +201,6 @@ BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int hei
                                                        dstp++;
                                                }
                                        }
-
-                                       return NULL;
                                }
                                else if (nRunLength > 31)
                                {
@@ -268,16 +263,23 @@ BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int hei
                                        dstp++;
 
                                        CopyMemory(dstp, rawValues, cRawBytes);
-                                       rawValues += cRawBytes;
                                        dstp += cRawBytes;
+
+                                       rawValues += (cRawBytes + nRunLength);
+                                       nRunLength = 0;
                                        cRawBytes = 0;
+
+                                       j--;
+                                       continue;
                                }
                        }
                        else
                        {
-                               cRawBytes += (nRunLength + 1);
-
-                               if (j == width)
+                               if (j != width)
+                               {
+                                       cRawBytes++;
+                               }
+                               else
                                {
                                        nRunLength = 0;
 
@@ -301,8 +303,8 @@ BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int hei
                                                dstp += 15;
                                        }
 
-#if 0
-                                       printf("RAW[");
+#if 1
+                                       printf("RAW[");
 
                                        for (k = 0; k < cRawBytes; k++)
                                        {
@@ -330,18 +332,9 @@ BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int hei
                                        cRawBytes = 0;
                                }
                        }
-
-                       if (j != width)
-                       {
-                               symbol = inPlane[(i * width) + j];
-                               nRunLength = 0;
-                       }
                }
-               //printf("---\n");
        }
 
-       //printf("\n");
-
        *dstSize = (dstp - outPlane);
 
        return outPlane;
index a0d58ff..1302b44 100644 (file)
@@ -1,4 +1,6 @@
 
+#include <winpr/crt.h>
+
 #include <freerdp/freerdp.h>
 #include <freerdp/codec/color.h>
 #include <freerdp/codec/bitmap.h>
@@ -213,11 +215,17 @@ const BYTE TEST_RDP6_SCANLINES_DELTA_2C_ENCODED_UNSIGNED[3][6] =
 
 int TestFreeRDPCodecPlanar(int argc, char* argv[])
 {
+       int i;
        int dstSize;
        UINT32 format;
        HCLRCONV clrconv;
        BYTE* srcBitmap32;
        BYTE* srcBitmap16;
+       int width, height;
+       BYTE* blackBitmap;
+       BYTE* whiteBitmap;
+       BYTE* compressedBitmap;
+       BYTE* decompressedBitmap;
 
        clrconv = freerdp_clrconv_new(0);
        srcBitmap16 = (BYTE*) TEST_RLE_UNCOMPRESSED_BITMAP_16BPP;
@@ -234,6 +242,70 @@ 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++)
+       {
+               width = i;
+               height = i;
+
+               if ((width > 17) && (width < 65))
+                       continue;
+
+               whiteBitmap = (BYTE*) malloc(width * height * 4);
+               FillMemory(whiteBitmap, width * height * 4, 0xFF);
+
+               compressedBitmap = freerdp_bitmap_compress_planar(whiteBitmap, 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 bitmap: width: %d height: %d\n", width, height);
+                       //return -1;
+               }
+               else
+               {
+                       printf("success decompressing bitmap: width: %d height: %d\n", width, height);
+               }
+
+               free(compressedBitmap);
+               free(decompressedBitmap);
+       }
+
+       return 0;
+
+       for (i = 17; i < 64; i++)
+       {
+               width = i;
+               height = i;
+
+               if ((width > 17) && (width < 65))
+                       continue;
+
+               blackBitmap = (BYTE*) malloc(width * height * 4);
+               ZeroMemory(blackBitmap, width * height * 4);
+
+               compressedBitmap = freerdp_bitmap_compress_planar(blackBitmap, 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 bitmap: width: %d height: %d\n", width, height);
+                       //return -1;
+               }
+               else
+               {
+                       printf("success decompressing bitmap: width: %d height: %d\n", width, height);
+               }
+
+               free(compressedBitmap);
+               free(decompressedBitmap);
+       }
+
        freerdp_clrconv_free(clrconv);
        free(srcBitmap32);