25 #include <freerdp/assistance.h>
27 #include <winpr/crt.h>
28 #include <winpr/print.h>
29 #include <winpr/platform.h>
30 #include <freerdp/codec/interleaved.h>
31 #include <freerdp/codec/planar.h>
32 #include <freerdp/codec/bulk.h>
33 #include <freerdp/codec/clear.h>
34 #include <freerdp/codec/zgfx.h>
35 #include <freerdp/log.h>
36 #include <winpr/bitstream.h>
37 #include <freerdp/codec/rfx.h>
38 #include <freerdp/codec/progressive.h>
40 #include <freerdp/freerdp.h>
41 #include <freerdp/gdi/gdi.h>
43 #include "../progressive.h"
45 #include "../xcrush.h"
46 #include "../ncrush.h"
48 static BOOL test_ClearDecompressExample(UINT32 nr, UINT32 width, UINT32 height,
49 const BYTE* pSrcData,
const UINT32 SrcSize)
53 BYTE* pDstData = calloc(1ull * width * height, 4);
54 CLEAR_CONTEXT* clear = clear_context_new(FALSE);
57 if (!clear || !pDstData)
60 status = clear_decompress(clear, pSrcData, SrcSize, width, height, pDstData,
61 PIXEL_FORMAT_XRGB32, 0, 0, 0, width, height, NULL);
66 clear_context_free(clear);
71 static int TestFreeRDPCodecClear(
const uint8_t* Data,
size_t Size)
73 if (Size > UINT32_MAX)
75 test_ClearDecompressExample(2, 78, 17, Data, (UINT32)Size);
76 test_ClearDecompressExample(3, 64, 24, Data, (UINT32)Size);
77 test_ClearDecompressExample(4, 7, 15, Data, (UINT32)Size);
81 static int TestFreeRDPCodecXCrush(
const uint8_t* Data,
size_t Size)
83 if (Size > UINT32_MAX)
86 const BYTE* OutputBuffer = NULL;
88 XCRUSH_CONTEXT* xcrush = xcrush_context_new(TRUE);
91 xcrush_decompress(xcrush, Data, (UINT32)Size, &OutputBuffer, &DstSize, 0);
92 xcrush_context_free(xcrush);
96 static int test_ZGfxDecompressFoxSingle(
const uint8_t* Data,
size_t Size)
98 if (Size > UINT32_MAX)
103 const BYTE* pSrcData = (
const BYTE*)Data;
104 UINT32 SrcSize = (UINT32)Size;
106 BYTE* pDstData = NULL;
107 ZGFX_CONTEXT* zgfx = zgfx_context_new(TRUE);
112 status = zgfx_decompress(zgfx, pSrcData, SrcSize, &pDstData, &DstSize, Flags);
119 zgfx_context_free(zgfx);
123 static int TestFreeRDPCodecZGfx(
const uint8_t* Data,
size_t Size)
125 test_ZGfxDecompressFoxSingle(Data, Size);
129 static BOOL test_NCrushDecompressBells(
const uint8_t* Data,
size_t Size)
131 if (Size > UINT32_MAX)
136 UINT32 Flags = PACKET_COMPRESSED | 2;
137 const BYTE* pSrcData = (
const BYTE*)Data;
138 UINT32 SrcSize = (UINT32)Size;
140 const BYTE* pDstData = NULL;
141 NCRUSH_CONTEXT* ncrush = ncrush_context_new(FALSE);
146 status = ncrush_decompress(ncrush, pSrcData, SrcSize, &pDstData, &DstSize, Flags);
152 ncrush_context_free(ncrush);
156 static int TestFreeRDPCodecNCrush(
const uint8_t* Data,
size_t Size)
158 test_NCrushDecompressBells(Data, Size);
162 static const size_t IMG_WIDTH = 64;
163 static const size_t IMG_HEIGHT = 64;
164 static const size_t FORMAT_SIZE = 4;
165 static const UINT32 FORMAT = PIXEL_FORMAT_XRGB32;
167 static int TestFreeRDPCodecRemoteFX(
const uint8_t* Data,
size_t Size)
171 RFX_CONTEXT* context = rfx_context_new(FALSE);
172 BYTE* dest = calloc(IMG_WIDTH * IMG_HEIGHT, FORMAT_SIZE);
173 size_t stride = FORMAT_SIZE * IMG_WIDTH;
176 if (Size > UINT32_MAX)
178 if (stride > UINT32_MAX)
183 region16_init(®ion);
184 if (!rfx_process_message(context, Data, (UINT32)Size, 0, 0, dest, FORMAT, (UINT32)stride,
185 IMG_HEIGHT, ®ion))
188 region16_clear(®ion);
189 if (!rfx_process_message(context, Data, (UINT32)Size, 0, 0, dest, FORMAT, (UINT32)stride,
190 IMG_HEIGHT, ®ion))
192 region16_print(®ion);
196 region16_uninit(®ion);
197 rfx_context_free(context);
202 static int test_MppcDecompressBellsRdp5(
const uint8_t* Data,
size_t Size)
206 UINT32 Flags = PACKET_AT_FRONT | PACKET_COMPRESSED | 1;
207 const BYTE* pSrcData = Data;
208 UINT32 SrcSize = (UINT32)Size;
210 const BYTE* pDstData = NULL;
211 MPPC_CONTEXT* mppc = mppc_context_new(1, FALSE);
216 status = mppc_decompress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, Flags);
224 mppc_context_free(mppc);
228 static int test_MppcDecompressBellsRdp4(
const uint8_t* Data,
size_t Size)
230 if (Size > UINT32_MAX)
234 UINT32 Flags = PACKET_AT_FRONT | PACKET_COMPRESSED | 0;
235 const BYTE* pSrcData = (
const BYTE*)Data;
236 UINT32 SrcSize = (UINT32)Size;
238 const BYTE* pDstData = NULL;
239 MPPC_CONTEXT* mppc = mppc_context_new(0, FALSE);
244 status = mppc_decompress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, Flags);
251 mppc_context_free(mppc);
255 static int test_MppcDecompressBufferRdp5(
const uint8_t* Data,
size_t Size)
257 if (Size > UINT32_MAX)
261 UINT32 Flags = PACKET_AT_FRONT | PACKET_COMPRESSED | 1;
262 const BYTE* pSrcData = (
const BYTE*)Data;
263 UINT32 SrcSize = (UINT32)Size;
265 const BYTE* pDstData = NULL;
266 MPPC_CONTEXT* mppc = mppc_context_new(1, FALSE);
271 status = mppc_decompress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, Flags);
278 mppc_context_free(mppc);
282 static int TestFreeRDPCodecMppc(
const uint8_t* Data,
size_t Size)
284 test_MppcDecompressBellsRdp5(Data, Size);
285 test_MppcDecompressBellsRdp4(Data, Size);
286 test_MppcDecompressBufferRdp5(Data, Size);
290 static BOOL progressive_decode(
const uint8_t* Data,
size_t Size)
294 BYTE* resultData = NULL;
295 UINT32 ColorFormat = PIXEL_FORMAT_BGRX32;
297 UINT32 scanline = 4240;
300 if (Size > UINT32_MAX)
303 PROGRESSIVE_CONTEXT* progressiveDec = progressive_context_new(FALSE);
305 region16_init(&invalidRegion);
309 resultData = calloc(scanline, height);
313 rc = progressive_create_surface_context(progressiveDec, 0, width, height);
317 rc = progressive_decompress(progressiveDec, Data, (UINT32)Size, resultData, ColorFormat,
318 scanline, 0, 0, &invalidRegion, 0, 0);
324 region16_uninit(&invalidRegion);
325 progressive_context_free(progressiveDec);
330 static int TestFreeRDPCodecProgressive(
const uint8_t* Data,
size_t Size)
332 progressive_decode(Data, Size);
336 static BOOL i_run_encode_decode(UINT16 bpp, BITMAP_INTERLEAVED_CONTEXT* encoder,
337 BITMAP_INTERLEAVED_CONTEXT* decoder,
const uint8_t* Data,
346 const UINT32 format = PIXEL_FORMAT_RGBX32;
347 const size_t step = (w + 13ull) * 4ull;
348 const size_t SrcSize = step * h;
349 BYTE* pSrcData = calloc(1, SrcSize);
350 BYTE* pDstData = calloc(1, SrcSize);
351 BYTE* tmp = calloc(1, SrcSize);
353 WINPR_UNUSED(encoder);
354 if (!pSrcData || !pDstData || !tmp)
357 if (Size > UINT32_MAX)
360 winpr_RAND(pSrcData, SrcSize);
362 if (!bitmap_interleaved_context_reset(decoder))
365 rc = interleaved_decompress(decoder, Data, (UINT32)Size, w, h, bpp, pDstData, format, step, x,
379 static int TestFreeRDPCodecInterleaved(
const uint8_t* Data,
size_t Size)
382 BITMAP_INTERLEAVED_CONTEXT* decoder = bitmap_interleaved_context_new(FALSE);
387 i_run_encode_decode(24, NULL, decoder, Data, Size);
388 i_run_encode_decode(16, NULL, decoder, Data, Size);
389 i_run_encode_decode(15, NULL, decoder, Data, Size);
392 bitmap_interleaved_context_free(decoder);
396 static BOOL RunTestPlanar(BITMAP_PLANAR_CONTEXT* planar,
const BYTE* srcBitmap,
397 const UINT32 srcFormat,
const UINT32 dstFormat,
const UINT32 width,
398 const UINT32 height,
const uint8_t* Data,
size_t Size)
401 WINPR_UNUSED(srcBitmap);
402 WINPR_UNUSED(srcFormat);
403 if (Size > UINT32_MAX)
405 UINT32 dstSize = (UINT32)Size;
406 const BYTE* compressedBitmap = Data;
407 BYTE* decompressedBitmap =
408 (BYTE*)calloc(height, 1ull * width * FreeRDPGetBytesPerPixel(dstFormat));
411 if (!decompressedBitmap)
414 if (!planar_decompress(planar, compressedBitmap, dstSize, width, height, decompressedBitmap,
415 dstFormat, 0, 0, 0, width, height, FALSE))
422 free(decompressedBitmap);
426 static BOOL TestPlanar(
const UINT32 format,
const uint8_t* Data,
size_t Size)
429 const DWORD planarFlags = PLANAR_FORMAT_HEADER_NA | PLANAR_FORMAT_HEADER_RLE;
430 BITMAP_PLANAR_CONTEXT* planar = freerdp_bitmap_planar_context_new(planarFlags, 64, 64);
435 RunTestPlanar(planar, NULL, PIXEL_FORMAT_RGBX32, format, 64, 64, Data, Size);
437 RunTestPlanar(planar, NULL, PIXEL_FORMAT_RGB16, format, 32, 32, Data, Size);
441 freerdp_bitmap_planar_context_free(planar);
445 static int TestFreeRDPCodecPlanar(
const uint8_t* Data,
size_t Size)
447 TestPlanar(0, Data, Size);
451 int LLVMFuzzerTestOneInput(
const uint8_t* Data,
size_t Size)
456 TestFreeRDPCodecClear(Data, Size);
457 TestFreeRDPCodecXCrush(Data, Size);
458 TestFreeRDPCodecZGfx(Data, Size);
459 TestFreeRDPCodecNCrush(Data, Size);
460 TestFreeRDPCodecRemoteFX(Data, Size);
461 TestFreeRDPCodecMppc(Data, Size);
462 TestFreeRDPCodecProgressive(Data, Size);
463 TestFreeRDPCodecInterleaved(Data, Size);
464 TestFreeRDPCodecPlanar(Data, Size);