#include #include #include #include #include #include #include #include #include #include static BOOL run_encode_decode_single(UINT16 bpp, BITMAP_INTERLEAVED_CONTEXT* encoder, BITMAP_INTERLEAVED_CONTEXT* decoder #if defined(WITH_PROFILER) , PROFILER* profiler_comp, PROFILER* profiler_decomp #endif ) { BOOL rc2 = FALSE; BOOL rc = 0; const UINT32 w = 64; const UINT32 h = 64; const UINT32 x = 0; const UINT32 y = 0; const UINT32 format = PIXEL_FORMAT_RGBX32; const UINT32 bstep = FreeRDPGetBytesPerPixel(format); const size_t step = (w + 13) * 4; const size_t SrcSize = step * h; const float maxDiff = 4.0f * ((bpp < 24) ? 2.0f : 1.0f); UINT32 DstSize = SrcSize; BYTE* pSrcData = calloc(1, SrcSize); BYTE* pDstData = calloc(1, SrcSize); BYTE* tmp = calloc(1, SrcSize); if (!pSrcData || !pDstData || !tmp) goto fail; winpr_RAND(pSrcData, SrcSize); if (!bitmap_interleaved_context_reset(encoder) || !bitmap_interleaved_context_reset(decoder)) goto fail; PROFILER_ENTER(profiler_comp) rc = interleaved_compress(encoder, tmp, &DstSize, w, h, pSrcData, format, step, x, y, NULL, bpp); PROFILER_EXIT(profiler_comp) if (!rc) goto fail; PROFILER_ENTER(profiler_decomp) rc = interleaved_decompress(decoder, tmp, DstSize, w, h, bpp, pDstData, format, step, x, y, w, h, NULL); PROFILER_EXIT(profiler_decomp) if (!rc) goto fail; for (UINT32 i = 0; i < h; i++) { const BYTE* srcLine = &pSrcData[i * step]; const BYTE* dstLine = &pDstData[i * step]; for (UINT32 j = 0; j < w; j++) { BYTE r = 0; BYTE g = 0; BYTE b = 0; BYTE dr = 0; BYTE dg = 0; BYTE db = 0; const UINT32 srcColor = FreeRDPReadColor(&srcLine[j * bstep], format); const UINT32 dstColor = FreeRDPReadColor(&dstLine[j * bstep], format); FreeRDPSplitColor(srcColor, format, &r, &g, &b, NULL, NULL); FreeRDPSplitColor(dstColor, format, &dr, &dg, &db, NULL, NULL); if (fabsf((float)r - dr) > maxDiff) goto fail; if (fabsf((float)g - dg) > maxDiff) goto fail; if (fabsf((float)b - db) > maxDiff) goto fail; } } rc2 = TRUE; fail: free(pSrcData); free(pDstData); free(tmp); return rc2; } static const char* get_profiler_name(BOOL encode, UINT16 bpp) { switch (bpp) { case 24: if (encode) return "interleaved_compress 24bpp"; else return "interleaved_decompress 24bpp"; case 16: if (encode) return "interleaved_compress 16bpp"; else return "interleaved_decompress 16bpp"; case 15: if (encode) return "interleaved_compress 15bpp"; else return "interleaved_decompress 15bpp"; default: return "configuration error!"; } } static BOOL run_encode_decode(UINT16 bpp, BITMAP_INTERLEAVED_CONTEXT* encoder, BITMAP_INTERLEAVED_CONTEXT* decoder) { BOOL rc = FALSE; PROFILER_DEFINE(profiler_comp) PROFILER_DEFINE(profiler_decomp) PROFILER_CREATE(profiler_comp, get_profiler_name(TRUE, bpp)) PROFILER_CREATE(profiler_decomp, get_profiler_name(FALSE, bpp)) for (UINT32 x = 0; x < 50; x++) { if (!run_encode_decode_single(bpp, encoder, decoder #if defined(WITH_PROFILER) , profiler_comp, profiler_decomp #endif )) goto fail; } rc = TRUE; fail: PROFILER_PRINT_HEADER PROFILER_PRINT(profiler_comp) PROFILER_PRINT(profiler_decomp) PROFILER_PRINT_FOOTER PROFILER_FREE(profiler_comp) PROFILER_FREE(profiler_decomp) return rc; } static BOOL TestColorConversion(void) { const UINT32 formats[] = { PIXEL_FORMAT_RGB15, PIXEL_FORMAT_BGR15, PIXEL_FORMAT_ABGR15, PIXEL_FORMAT_ARGB15, PIXEL_FORMAT_BGR16, PIXEL_FORMAT_RGB16 }; /* Check color conversion 15/16 -> 32bit maps to proper values */ for (UINT32 x = 0; x < ARRAYSIZE(formats); x++) { const UINT32 dstFormat = PIXEL_FORMAT_RGBA32; const UINT32 format = formats[x]; const UINT32 colorLow = FreeRDPGetColor(format, 0, 0, 0, 255); const UINT32 colorHigh = FreeRDPGetColor(format, 255, 255, 255, 255); const UINT32 colorLow32 = FreeRDPConvertColor(colorLow, format, dstFormat, NULL); const UINT32 colorHigh32 = FreeRDPConvertColor(colorHigh, format, dstFormat, NULL); BYTE r = 0; BYTE g = 0; BYTE b = 0; BYTE a = 0; FreeRDPSplitColor(colorLow32, dstFormat, &r, &g, &b, &a, NULL); if ((r != 0) || (g != 0) || (b != 0)) return FALSE; FreeRDPSplitColor(colorHigh32, dstFormat, &r, &g, &b, &a, NULL); if ((r != 255) || (g != 255) || (b != 255)) return FALSE; } return TRUE; } int TestFreeRDPCodecInterleaved(int argc, char* argv[]) { BITMAP_INTERLEAVED_CONTEXT* encoder = NULL; BITMAP_INTERLEAVED_CONTEXT* decoder = NULL; int rc = -1; WINPR_UNUSED(argc); WINPR_UNUSED(argv); encoder = bitmap_interleaved_context_new(TRUE); decoder = bitmap_interleaved_context_new(FALSE); if (!encoder || !decoder) goto fail; if (!run_encode_decode(24, encoder, decoder)) goto fail; if (!run_encode_decode(16, encoder, decoder)) goto fail; if (!run_encode_decode(15, encoder, decoder)) goto fail; if (!TestColorConversion()) goto fail; rc = 0; fail: bitmap_interleaved_context_free(encoder); bitmap_interleaved_context_free(decoder); return rc; }