libfreerdp-primitives: update YCbCr test code

This commit is contained in:
Marc-André Moreau 2014-09-09 13:44:57 -04:00
parent 81454c1171
commit 12ca7b3391

View File

@ -2,6 +2,7 @@
#include "prim_test.h" #include "prim_test.h"
#include <winpr/print.h> #include <winpr/print.h>
#include <freerdp/codec/color.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
@ -2075,78 +2076,98 @@ static UINT32 TEST_XRGB_IMAGE[4096] =
0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5
}; };
static int test_memcmp_offset(const BYTE* mem1, const BYTE* mem2, int size) static int test_bmp_cmp_offset(const BYTE* mem1, const BYTE* mem2, int size, int channel)
{ {
int index = 0; int index = 0;
size /= 4;
mem1 += channel;
mem2 += channel;
while ((index < size) && (*mem1 == *mem2)) while ((index < size) && (*mem1 == *mem2))
{ {
mem1++; mem1 += 4;
mem2++; mem2 += 4;
index++; index++;
} }
return (index == size) ? 1 : -index; return (index == size) ? 1 : -index;
} }
static int test_memcmp_count(const BYTE* mem1, const BYTE* mem2, int size) static int test_bmp_cmp_count(const BYTE* mem1, const BYTE* mem2, int size, int channel)
{ {
int count = 0; int count = 0;
int index = 0; int index = 0;
size /= 4;
mem1 += channel;
mem2 += channel;
for (index = 0; index < size; index++) for (index = 0; index < size; index++)
{ {
if (*mem1 != *mem2) if (*mem1 != *mem2)
count++; count++;
mem1++; mem1 += 4;
mem2++; mem2 += 4;
} }
return count; return count;
} }
static void test_fill_bitmap_red_channel(BYTE* data, int width, int height, BYTE value) static int test_bmp_cmp_dump(const BYTE* actual, const BYTE* expected, int size, int channel)
{ {
int i, j; UINT32 pixel;
UINT32* pixel; int count = 0;
int index = 0;
BYTE R, G, B;
BYTE eR, eG, eB;
INT16 Y, Cb, Cr;
for (i = 0; i < height; i++) size /= 4;
actual += channel;
expected += channel;
for (index = 0; index < size; index++)
{ {
for (j = 0; j < width; j++) if (*actual != *expected)
{ {
pixel = (UINT32*) &data[((i * width) + j) * 4]; pixel = *((UINT32*) &actual[-channel]);
*pixel = ((*pixel & 0xFF00FFFF) | (value << 16)); GetRGB32(R, G, B, pixel);
pixel = *((UINT32*) &expected[-channel]);
GetRGB32(eR, eG, eB, pixel);
Y = TEST_Y_COMPONENT[index];
Cb = TEST_CB_COMPONENT[index];
Cr = TEST_CR_COMPONENT[index];
printf("Idx: %d Y: %+5d Cb: %+5d Cr: %+5d Actual: R: %3d G: %3d B: %3d Expected: R: %3d G: %3d B: %3d\n",
index, Y, Cb, Cr, R, G, B, eR, eG, eB);
count++;
} }
actual += 4;
expected += 4;
} }
return count;
} }
static void test_fill_bitmap_green_channel(BYTE* data, int width, int height, BYTE value) static void test_fill_bitmap_channel(BYTE* data, int width, int height, BYTE value, int nChannel)
{ {
int i, j; int x, y;
UINT32* pixel; BYTE* pChannel;
for (i = 0; i < height; i++) pChannel = data + nChannel;
{
for (j = 0; j < width; j++)
{
pixel = (UINT32*) &data[((i * width) + j) * 4];
*pixel = ((*pixel & 0xFFFF00FF) | (value << 8));
}
}
}
static void test_fill_bitmap_blue_channel(BYTE* data, int width, int height, BYTE value) for (y = 0; y < height; y++)
{
int i, j;
UINT32* pixel;
for (i = 0; i < height; i++)
{ {
for (j = 0; j < width; j++) for (x = 0; x < width; x++)
{ {
pixel = (UINT32*) &data[((i * width) + j) * 4]; *pChannel = value;
*pixel = ((*pixel & 0xFFFFFF00) | (value)); pChannel += 4;
} }
} }
} }
@ -2170,14 +2191,36 @@ int test_YCbCr_fp(TEST_FP_TYPE coeffs[4], INT16 YCbCr[3], BYTE RGB[3])
{ {
INT16 R, G, B; INT16 R, G, B;
TEST_FP_TYPE Y, Cb, Cr; TEST_FP_TYPE Y, Cb, Cr;
TEST_FP_TYPE fR, fG, fB;
Y = (TEST_FP_TYPE) (YCbCr[0] + 4096); Y = (TEST_FP_TYPE) (YCbCr[0] + 4096);
Cb = (TEST_FP_TYPE) (YCbCr[1]); Cb = (TEST_FP_TYPE) (YCbCr[1]);
Cr = (TEST_FP_TYPE) (YCbCr[2]); Cr = (TEST_FP_TYPE) (YCbCr[2]);
#if 1
fR = ((Cr * coeffs[0]) + Y + 16.0f);
fG = (Y - (Cb * coeffs[1]) - (Cr * coeffs[2]) + 16.0f);
fB = ((Cb * coeffs[3]) + Y + 16.0f);
printf("fR: %f fG: %f fB: %f\n", fR, fG, fB);
R = (INT16) fR;
G = (INT16) fG;
B = (INT16) fB;
printf("iR: %d iG: %d iB: %d\n", R, G, B);
R >>= 5;
G >>= 5;
B >>= 5;
printf("R5: %d G5: %d B5: %d\n", R, G, B);
#else
R = ((INT16) (((Cr * coeffs[0]) + Y + 16.0f)) >> 5); R = ((INT16) (((Cr * coeffs[0]) + Y + 16.0f)) >> 5);
G = ((INT16) ((Y - (Cb * coeffs[1]) - (Cr * coeffs[2]) + 16.0f)) >> 5); G = ((INT16) ((Y - (Cb * coeffs[1]) - (Cr * coeffs[2]) + 16.0f)) >> 5);
B = ((INT16) (((Cb * coeffs[3]) + Y + 16.0f)) >> 5); B = ((INT16) (((Cb * coeffs[3]) + Y + 16.0f)) >> 5);
#endif
if (R < 0) if (R < 0)
R = 0; R = 0;
@ -2203,7 +2246,7 @@ int test_YCbCr_fp(TEST_FP_TYPE coeffs[4], INT16 YCbCr[3], BYTE RGB[3])
//printf("[1]: %20.20lf\n", coeffs[1]); //printf("[1]: %20.20lf\n", coeffs[1]);
//printf("[2]: %20.20lf\n", coeffs[2]); //printf("[2]: %20.20lf\n", coeffs[2]);
//printf("[3]: %20.20lf\n", coeffs[3]); //printf("[3]: %20.20lf\n", coeffs[3]);
printf("--------------------------------\n"); printf("--------------------------------\n\n");
return 0; return 0;
} }
@ -2236,16 +2279,17 @@ int test_YCbCr_pixels()
int TestPrimitivesYCbCr(int argc, char* argv[]) int TestPrimitivesYCbCr(int argc, char* argv[])
{ {
int cmp;
int cnt;
int size; int size;
int cmp[3];
int cnt[3];
float err[3];
BYTE* actual; BYTE* actual;
BYTE* expected; BYTE* expected;
INT16* pYCbCr[3]; INT16* pYCbCr[3];
const primitives_t* prims = primitives_get(); const primitives_t* prims = primitives_get();
static const prim_size_t roi_64x64 = { 64, 64 }; static const prim_size_t roi_64x64 = { 64, 64 };
return test_YCbCr_pixels(); //return test_YCbCr_pixels();
expected = (BYTE*) TEST_XRGB_IMAGE; expected = (BYTE*) TEST_XRGB_IMAGE;
@ -2289,41 +2333,52 @@ int TestPrimitivesYCbCr(int argc, char* argv[])
_aligned_free(pSrcDst[2]); _aligned_free(pSrcDst[2]);
} }
if (1) if (0)
{ {
test_fill_bitmap_red_channel(actual, 64, 64, 0); test_fill_bitmap_channel(actual, 64, 64, 0, 2); /* red */
test_fill_bitmap_red_channel(expected, 64, 64, 0); test_fill_bitmap_channel(expected, 64, 64, 0, 2); /* red */
}
if (1)
{
test_fill_bitmap_green_channel(actual, 64, 64, 0);
test_fill_bitmap_green_channel(expected, 64, 64, 0);
} }
if (0) if (0)
{ {
test_fill_bitmap_blue_channel(actual, 64, 64, 0); test_fill_bitmap_channel(actual, 64, 64, 0, 1); /* green */
test_fill_bitmap_blue_channel(expected, 64, 64, 0); test_fill_bitmap_channel(expected, 64, 64, 0, 1); /* green */
} }
cmp = test_memcmp_offset(actual, expected, size); if (0)
cnt = test_memcmp_count(actual, expected, size);
if (cmp <= 0)
{ {
cmp *= -1; test_fill_bitmap_channel(actual, 64, 64, 0, 0); /* blue */
float rate = ((float) cnt) / ((float) size) * 100.0f; test_fill_bitmap_channel(expected, 64, 64, 0, 0); /* blue */
printf("YCbCr to RGB conversion failure\n");
printf("Actual, Expected (offset: %d diff: %d/%d = %d%%):\n",
cmp, cnt, size, (int) rate);
winpr_HexDump(&actual[cmp], 16);
winpr_HexDump(&expected[cmp], 16);
} }
cmp[2] = test_bmp_cmp_offset(actual, expected, size, 2); /* red */
cnt[2] = test_bmp_cmp_count(actual, expected, size, 2); /* red */
err[2] = ((float) cnt[2]) / ((float) size / 4) * 100.0f;
cmp[1] = test_bmp_cmp_offset(actual, expected, size, 1); /* green */
cnt[1] = test_bmp_cmp_count(actual, expected, size, 1); /* green */
err[1] = ((float) cnt[1]) / ((float) size / 4) * 100.0f;
cmp[0] = test_bmp_cmp_offset(actual, expected, size, 0); /* blue */
cnt[0] = test_bmp_cmp_count(actual, expected, size, 0); /* blue */
err[0] = ((float) cnt[0]) / ((float) size / 4) * 100.0f;
if (0)
{
printf("Red Error Dump:\n");
test_bmp_cmp_dump(actual, expected, size, 2); /* red */
printf("Green Error Dump:\n");
test_bmp_cmp_dump(actual, expected, size, 1); /* green */
printf("Blue Error Dump:\n");
test_bmp_cmp_dump(actual, expected, size, 0); /* blue */
}
printf("R: diff: %d (%f%%)\n", cnt[2], err[2]);
printf("G: diff: %d (%f%%)\n", cnt[1], err[1]);
printf("B: diff: %d (%f%%)\n", cnt[0], err[0]);
_aligned_free(actual); _aligned_free(actual);
return 0; return 0;