libfreerdp-primitives: add per-pixel YCbCr test code
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Mon, 8 Sep 2014 19:16:03 +0000 (15:16 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Mon, 8 Sep 2014 19:16:03 +0000 (15:16 -0400)
libfreerdp/primitives/prim_colors.c
libfreerdp/primitives/test/TestPrimitivesYCbCr.c

index 7464159..a183159 100644 (file)
@@ -39,7 +39,7 @@ pstatus_t general_yCbCrToRGB_16s8u_P3AC4R(const INT16* pSrc[3], int srcStep,
 {
        int x, y;
        INT16 R, G, B;
-       double Y, Cb, Cr;
+       float Y, Cb, Cr;
        BYTE* pRGB = pDst;
        const INT16* pY  = pSrc[0];
        const INT16* pCb = pSrc[1];
@@ -51,13 +51,13 @@ pstatus_t general_yCbCrToRGB_16s8u_P3AC4R(const INT16* pSrc[3], int srcStep,
        {
                for (x = 0; x < roi->width; x++)
                {
-                       Y = (double) (pY[0] + 4096);
-                       Cb = (double) (pCb[0]);
-                       Cr = (double) (pCr[0]);
+                       Y = (float) (pY[0] + 4096);
+                       Cb = (float) (pCb[0]);
+                       Cr = (float) (pCr[0]);
 
-                       R = ((INT16) (((Cr * 1.402524948120117L) + Y + 16.0L)) >> 5);
-                       G = ((INT16) ((Y - (Cb * 0.3437300026416779L) - (Cr * 0.7144010066986084L) + 16.0L)) >> 5);
-                       B = ((INT16) (((Cb * 1.769904971122742L) + Y + 16.0L)) >> 5);
+                       R = ((INT16) (((Cr * 1.402525f) + Y + 16.0f)) >> 5);
+                       G = ((INT16) ((Y - (Cb * 0.343730f) - (Cr * 0.714401f) + 16.0f)) >> 5);
+                       B = ((INT16) (((Cb * 1.769905f) + Y + 16.0f)) >> 5);
 
                        if (R < 0)
                                R = 0;
index 26c2169..79e6347 100644 (file)
@@ -2151,6 +2151,79 @@ static void test_fill_bitmap_blue_channel(BYTE* data, int width, int height, BYT
        }
 }
 
+static float TEST_YCbCrToRGB_01[4] = { 1.403f,    0.344f,    0.714f,    1.770f    };
+static float TEST_YCbCrToRGB_02[4] = { 1.402525f, 0.343730f, 0.714401f, 1.769905f };
+
+static INT16 TEST_YCbCr_01[3] = { +115, +1720, -2145 };
+static BYTE TEST_RGB_01[3] = { 37, 161, 227 }; /* incorrect red */
+
+static INT16 TEST_YCbCr_02[3] = { -450, +1938, -2126 };
+static BYTE TEST_RGB_02[3] = { 21, 140, 221 }; /* incorrect green */
+
+static INT16 TEST_YCbCr_03[3] = { -504, +1896, -2168 };
+static BYTE TEST_RGB_03[3] = { 17, 140, 217 }; /* incorrect blue */
+
+int test_YCbCr_fp(float coeffs[4], INT16 YCbCr[3], BYTE RGB[3])
+{
+       INT16 R, G, B;
+       float Y, Cb, Cr;
+
+       Y = (float) (YCbCr[0] + 4096);
+       Cb = (float) (YCbCr[1]);
+       Cr = (float) (YCbCr[2]);
+
+       R = ((INT16) (((Cr * coeffs[0]) + Y + 16.0f)) >> 5);
+       G = ((INT16) ((Y - (Cb * coeffs[1]) - (Cr * coeffs[2]) + 16.0f)) >> 5);
+       B = ((INT16) (((Cb * coeffs[3]) + Y + 16.0f)) >> 5);
+
+       if (R < 0)
+               R = 0;
+       else if (R > 255)
+               R = 255;
+
+       if (G < 0)
+               G = 0;
+       else if (G > 255)
+               G = 255;
+
+       if (B < 0)
+               B = 0;
+       else if (B > 255)
+               B = 255;
+
+       printf("--------------------------------\n");
+       printf("R: A: %3d E: %3d %s\n", R, RGB[0], (R == RGB[0]) ? "" : "***");
+       printf("G: A: %3d E: %3d %s\n", G, RGB[1], (G == RGB[1]) ? "" : "***");
+       printf("B: A: %3d E: %3d %s\n", B, RGB[2], (B == RGB[2]) ? "" : "***");
+       printf("Y: %+5d Cb: %+5d Cr: %+5d\n", YCbCr[0], YCbCr[1], YCbCr[2]);
+       printf("[0]: %20.16f\n", coeffs[0]);
+       printf("[1]: %20.16f\n", coeffs[1]);
+       printf("[2]: %20.16f\n", coeffs[2]);
+       printf("[3]: %20.16f\n", coeffs[3]);
+       printf("--------------------------------\n");
+
+       return 0;
+}
+
+int test_YCbCr_pixels()
+{
+       if (0)
+       {
+               test_YCbCr_fp(TEST_YCbCrToRGB_01, TEST_YCbCr_01, TEST_RGB_01);
+               test_YCbCr_fp(TEST_YCbCrToRGB_01, TEST_YCbCr_02, TEST_RGB_02);
+               test_YCbCr_fp(TEST_YCbCrToRGB_01, TEST_YCbCr_03, TEST_RGB_03);
+       }
+
+       if (1)
+       {
+               test_YCbCr_fp(TEST_YCbCrToRGB_02, TEST_YCbCr_01, TEST_RGB_01);
+               test_YCbCr_fp(TEST_YCbCrToRGB_02, TEST_YCbCr_02, TEST_RGB_02);
+               test_YCbCr_fp(TEST_YCbCrToRGB_02, TEST_YCbCr_03, TEST_RGB_03);
+       }
+
+       return 0;
+}
+
 int TestPrimitivesYCbCr(int argc, char* argv[])
 {
        int cmp;
@@ -2162,6 +2235,8 @@ int TestPrimitivesYCbCr(int argc, char* argv[])
        const primitives_t* prims = primitives_get();
        static const prim_size_t roi_64x64 = { 64, 64 };
 
+       return test_YCbCr_pixels();
+
        expected = (BYTE*) TEST_XRGB_IMAGE;
 
        size = 64 * 64 * 4;
@@ -2204,13 +2279,13 @@ int TestPrimitivesYCbCr(int argc, char* argv[])
                _aligned_free(pSrcDst[2]);
        }
 
-       if (0)
+       if (1)
        {
                test_fill_bitmap_red_channel(actual, 64, 64, 0);
                test_fill_bitmap_red_channel(expected, 64, 64, 0);
        }
 
-       if (0)
+       if (1)
        {
                test_fill_bitmap_green_channel(actual, 64, 64, 0);
                test_fill_bitmap_green_channel(expected, 64, 64, 0);