6#include <winpr/print.h>
7#include <winpr/crypto.h>
10#include <freerdp/freerdp.h>
11#include <freerdp/codec/color.h>
12#include <freerdp/codec/bitmap.h>
13#include <freerdp/codec/planar.h>
15#include "TestFreeRDPHelpers.h"
17static const UINT32 colorFormatList[] = {
18 PIXEL_FORMAT_RGB15, PIXEL_FORMAT_BGR15, PIXEL_FORMAT_RGB16, PIXEL_FORMAT_BGR16,
19 PIXEL_FORMAT_RGB24, PIXEL_FORMAT_BGR24, PIXEL_FORMAT_ARGB32, PIXEL_FORMAT_ABGR32,
20 PIXEL_FORMAT_XRGB32, PIXEL_FORMAT_XBGR32, PIXEL_FORMAT_RGBX32, PIXEL_FORMAT_BGRX32
23static const UINT32 colorFormatCount =
sizeof(colorFormatList) /
sizeof(colorFormatList[0]);
25static BOOL CompareBitmap(
const BYTE* srcA, UINT32 srcAFormat,
const BYTE* srcB, UINT32 srcBFormat,
26 UINT32 width, UINT32 height)
29 const UINT32 srcABits = FreeRDPGetBitsPerPixel(srcAFormat);
30 const UINT32 srcBBits = FreeRDPGetBitsPerPixel(srcBFormat);
31 UINT32 diff = WINPR_ASSERTING_INT_CAST(uint32_t, fabs((
double)srcABits - srcBBits));
34 if ((srcABits < 15) || (srcBBits < 15))
60 if ((srcABits == 32) || (srcBBits == 32))
66 for (
size_t y = 0; y < height; y++)
68 const BYTE* lineA = &srcA[y * width * FreeRDPGetBytesPerPixel(srcAFormat)];
69 const BYTE* lineB = &srcB[y * width * FreeRDPGetBytesPerPixel(srcBFormat)];
71 for (
size_t x = 0; x < width; x++)
81 const BYTE* a = &lineA[x * FreeRDPGetBytesPerPixel(srcAFormat)];
82 const BYTE* b = &lineB[x * FreeRDPGetBytesPerPixel(srcBFormat)];
83 UINT32 colorA = FreeRDPReadColor(a, srcAFormat);
84 UINT32 colorB = FreeRDPReadColor(b, srcBFormat);
85 FreeRDPSplitColor(colorA, srcAFormat, &sR, &sG, &sB, &sA, NULL);
86 FreeRDPSplitColor(colorB, srcBFormat, &dR, &dG, &dB, &dA, NULL);
88 if (fabs((
double)sR - dR) > maxDiff)
91 if (fabs((
double)sG - dG) > maxDiff)
94 if (fabs((
double)sB - dB) > maxDiff)
97 if (fabs((
double)sA - dA) > maxDiff)
105static BOOL RunTestPlanar(BITMAP_PLANAR_CONTEXT* encplanar, BITMAP_PLANAR_CONTEXT* decplanar,
106 const char* name,
const UINT32 srcFormat,
const UINT32 dstFormat,
107 const UINT32 width,
const UINT32 height)
109 WINPR_ASSERT(encplanar);
110 WINPR_ASSERT(decplanar);
114 (void)printf(
"---------------------- start %s [%s] ----------------------\n", __func__, name);
115 BYTE* srcBitmap = test_codec_helper_read_data(
"planar",
"bmp", name, &srclen);
119 BYTE* compressedBitmap = freerdp_bitmap_compress_planar(encplanar, srcBitmap, srcFormat, width,
120 height, 0, NULL, &dstSize);
121 BYTE* decompressedBitmap =
122 (BYTE*)calloc(height, 1ULL * width * FreeRDPGetBytesPerPixel(dstFormat));
124 if (!test_codec_helper_compare(
"planar",
"enc", name, compressedBitmap, dstSize))
127 (void)printf(
"%s [%s] --> [%s]: ", __func__, FreeRDPGetColorFormatName(srcFormat),
128 FreeRDPGetColorFormatName(dstFormat));
130 if (!compressedBitmap || !decompressedBitmap)
133 if (!freerdp_bitmap_decompress_planar(decplanar, compressedBitmap, dstSize, width, height,
134 decompressedBitmap, dstFormat, 0, 0, 0, width, height,
137 (void)printf(
"failed to decompress experimental bitmap 01: width: %" PRIu32
138 " height: %" PRIu32
"\n",
144 if (!compare(
"dec", name, decompressedBitmap,
145 1ull * width * height * FreeRDPGetBytesPerPixel(dstFormat)))
148 if (!CompareBitmap(decompressedBitmap, dstFormat, srcBitmap, srcFormat, width, height))
158 free(compressedBitmap);
159 free(decompressedBitmap);
161 (void)printf(
"%s [%s]: %s\n", __func__, name, rc ?
"SUCCESS" :
"FAILED");
162 (void)printf(
"---------------------- end %s [%s] ----------------------\n", __func__, name);
163 (void)fflush(stdout);
164 (void)fflush(stderr);
168static BOOL RunTestPlanarSingleColor(BITMAP_PLANAR_CONTEXT* planar,
const UINT32 srcFormat,
169 const UINT32 dstFormat)
172 (void)printf(
"%s: [%s] --> [%s]: ", __func__, FreeRDPGetColorFormatName(srcFormat),
173 FreeRDPGetColorFormatName(dstFormat));
174 (void)fflush(stdout);
175 (void)fflush(stderr);
177 for (UINT32 j = 0; j < 32; j += 8)
179 for (UINT32 i = 4; i < 32; i += 8)
181 UINT32 compressedSize = 0;
182 const UINT32 fill = j;
183 const UINT32 color = FreeRDPGetColor(srcFormat, (fill >> 8) & 0xF, (fill >> 4) & 0xF,
185 const UINT32 width = i;
186 const UINT32 height = i;
188 const UINT32 srcSize = width * height * FreeRDPGetBytesPerPixel(srcFormat);
189 const UINT32 dstSize = width * height * FreeRDPGetBytesPerPixel(dstFormat);
190 BYTE* compressedBitmap = NULL;
191 BYTE* bmp = malloc(srcSize);
192 BYTE* decompressedBitmap = (BYTE*)malloc(dstSize);
194 if (!bmp || !decompressedBitmap)
197 for (
size_t y = 0; y < height; y++)
199 BYTE* line = &bmp[y * width * FreeRDPGetBytesPerPixel(srcFormat)];
201 for (
size_t x = 0; x < width; x++)
203 FreeRDPWriteColor(line, srcFormat, color);
204 line += FreeRDPGetBytesPerPixel(srcFormat);
208 compressedBitmap = freerdp_bitmap_compress_planar(planar, bmp, srcFormat, width, height,
209 0, NULL, &compressedSize);
211 if (!compressedBitmap)
214 if (!freerdp_bitmap_decompress_planar(planar, compressedBitmap, compressedSize, width,
215 height, decompressedBitmap, dstFormat, 0, 0, 0,
216 width, height, FALSE))
219 if (!CompareBitmap(decompressedBitmap, dstFormat, bmp, srcFormat, width, height))
225 free(compressedBitmap);
226 free(decompressedBitmap);
239 (void)printf(
"%s [%s->%s]: %s\n", __func__, FreeRDPGetColorFormatName(srcFormat),
240 FreeRDPGetColorFormatName(dstFormat), rc ?
"SUCCESS" :
"FAILED");
241 (void)fflush(stdout);
242 (void)fflush(stderr);
246static BOOL TestPlanar(
const UINT32 format)
249 const DWORD planarFlags = PLANAR_FORMAT_HEADER_NA | PLANAR_FORMAT_HEADER_RLE;
250 BITMAP_PLANAR_CONTEXT* encplanar = freerdp_bitmap_planar_context_new(planarFlags, 64, 64);
251 BITMAP_PLANAR_CONTEXT* decplanar = freerdp_bitmap_planar_context_new(planarFlags, 64, 64);
253 if (!encplanar || !decplanar)
256 if (!RunTestPlanar(encplanar, decplanar,
"TEST_RLE_BITMAP_EXPERIMENTAL_01", PIXEL_FORMAT_RGBX32,
260 if (!RunTestPlanar(encplanar, decplanar,
"TEST_RLE_BITMAP_EXPERIMENTAL_02", PIXEL_FORMAT_RGBX32,
264 if (!RunTestPlanar(encplanar, decplanar,
"TEST_RLE_BITMAP_EXPERIMENTAL_03", PIXEL_FORMAT_RGBX32,
268 if (!RunTestPlanar(encplanar, decplanar,
"TEST_RLE_UNCOMPRESSED_BITMAP_16BPP",
269 PIXEL_FORMAT_RGB16, format, 32, 32))
272 for (UINT32 x = 0; x < colorFormatCount; x++)
274 if (!RunTestPlanarSingleColor(encplanar, format, colorFormatList[x]))
280 freerdp_bitmap_planar_context_free(encplanar);
281 freerdp_bitmap_planar_context_free(decplanar);
285static UINT32 prand(UINT32 max)
290 winpr_RAND(&tmp,
sizeof(tmp));
291 return tmp % (max - 1) + 1;
294static BOOL FuzzPlanar(
void)
296 (void)printf(
"---------------------- start %s ----------------------\n", __func__);
298 const DWORD planarFlags = PLANAR_FORMAT_HEADER_NA | PLANAR_FORMAT_HEADER_RLE;
299 BITMAP_PLANAR_CONTEXT* planar = freerdp_bitmap_planar_context_new(planarFlags, 64, 64);
304 for (UINT32 x = 0; x < 100; x++)
306 BYTE data[0x10000] = { 0 };
307 size_t dataSize = 0x10000;
308 BYTE dstData[0x10000] = { 0 };
310 UINT32 DstFormat = 0;
314 UINT32 nDstWidth = 0;
315 UINT32 nDstHeight = 0;
319 switch (prand(17) - 1)
322 DstFormat = PIXEL_FORMAT_RGB8;
325 DstFormat = PIXEL_FORMAT_BGR15;
328 DstFormat = PIXEL_FORMAT_RGB15;
331 DstFormat = PIXEL_FORMAT_ABGR15;
334 DstFormat = PIXEL_FORMAT_ABGR15;
337 DstFormat = PIXEL_FORMAT_BGR16;
340 DstFormat = PIXEL_FORMAT_RGB16;
343 DstFormat = PIXEL_FORMAT_BGR24;
346 DstFormat = PIXEL_FORMAT_RGB24;
349 DstFormat = PIXEL_FORMAT_BGRA32;
352 DstFormat = PIXEL_FORMAT_BGRX32;
355 DstFormat = PIXEL_FORMAT_RGBA32;
358 DstFormat = PIXEL_FORMAT_RGBX32;
361 DstFormat = PIXEL_FORMAT_ABGR32;
364 DstFormat = PIXEL_FORMAT_XBGR32;
367 DstFormat = PIXEL_FORMAT_ARGB32;
370 DstFormat = PIXEL_FORMAT_XRGB32;
375 nDstStep = prand(
sizeof(dstData));
376 nXDst = prand(nDstStep);
377 nYDst = prand(
sizeof(dstData) / nDstStep);
378 nDstWidth = prand(nDstStep / FreeRDPGetBytesPerPixel(DstFormat));
379 nDstHeight = prand(
sizeof(dstData) / nDstStep);
380 invalid = nXDst * FreeRDPGetBytesPerPixel(DstFormat) + (nYDst + nDstHeight) * nDstStep >
383 printf(
"DstFormat=%s, nXDst=%" PRIu32
", nYDst=%" PRIu32
", nDstWidth=%" PRIu32
384 ", nDstHeight=%" PRIu32
", nDstStep=%" PRIu32
", total size=%" PRIuz
"\n",
385 FreeRDPGetColorFormatName(DstFormat), nXDst, nYDst, nDstWidth, nDstHeight, nDstStep,
387 freerdp_planar_switch_bgr(planar, ((prand(2) % 2) != 0) ? TRUE : FALSE);
388 freerdp_bitmap_decompress_planar(planar, data, dataSize, prand(4096), prand(4096), dstData,
389 DstFormat, nDstStep, nXDst, nYDst, nDstWidth, nDstHeight,
390 ((prand(2) % 2) != 0) ? TRUE : FALSE);
395 freerdp_bitmap_planar_context_free(planar);
397 (void)printf(
"%s: %s\n", __func__, rc ?
"SUCCESS" :
"FAILED");
398 (void)printf(
"---------------------- end %s ----------------------\n", __func__);
399 (void)fflush(stdout);
400 (void)fflush(stderr);
404int TestFreeRDPCodecPlanar(
int argc,
char* argv[])
413 for (UINT32 x = 0; x < colorFormatCount; x++)
415 if (!TestPlanar(colorFormatList[x]))
421 printf(
"test returned %d\n", rc);