FreeRDP
Loading...
Searching...
No Matches
TestShadowCaptureCompare.c
1#include <stdio.h>
2#include <string.h>
3
4#include <winpr/wtypes.h>
5#include <freerdp/codec/color.h>
6#include <freerdp/server/shadow.h>
7
8/* The same picture in any 32 bpp format. */
9WINPR_ATTR_NODISCARD
10static BOOL fill(BYTE* data, size_t width, size_t height, UINT32 format, BYTE pad)
11{
12 for (size_t y = 0; y < height; y++)
13 {
14 for (size_t x = 0; x < width; x++)
15 {
16 BYTE* pixel = &data[(y * width + x) * 4ull];
17 const UINT32 color =
18 FreeRDPGetColor(format, (BYTE)(x * 4ull), (BYTE)(y * 5ull), (BYTE)(x ^ y), pad);
19 if (!FreeRDPWriteColor(pixel, format, color))
20 return FALSE;
21 }
22 }
23 return TRUE;
24}
25
26WINPR_ATTR_NODISCARD
27static BOOL expect(const BYTE* surface, size_t surfaceWidth, size_t surfaceHeight,
28 const BYTE* capture, size_t captureWidth, size_t captureHeight, const char* what,
29 UINT32 format1, UINT32 format2, int expectedStatus,
30 const RECTANGLE_16* expectedRect)
31{
32 RECTANGLE_16 rect = { 0 };
33 const int status = shadow_capture_compare_with_format(surface, format1, surfaceWidth * 4ull,
34 surfaceWidth, surfaceHeight, capture,
35 format2, captureWidth * 4ull, &rect);
36 BOOL ok = (status == expectedStatus);
37 if (ok && expectedRect)
38 ok = (memcmp(&rect, expectedRect, sizeof(rect)) == 0);
39 if (!ok)
40 (void)fprintf(stderr,
41 "%s: %s vs %s: status %d, rect %" PRIu16 ",%" PRIu16 "-%" PRIu16 ",%" PRIu16
42 ", expected status %d\n",
43 what, FreeRDPGetColorFormatName(format1), FreeRDPGetColorFormatName(format2),
44 status, rect.left, rect.top, rect.right, rect.bottom, expectedStatus);
45 return ok;
46}
47
48/* The padding byte of an X format pixel lives where the alpha of its A twin does. */
49static void set_padding(BYTE* data, size_t width, size_t height, UINT32 alphaFormat, BYTE pad)
50{
51 BYTE alpha[4] = { 0 };
52 (void)FreeRDPWriteColor(alpha, alphaFormat, FreeRDPGetColor(alphaFormat, 0, 0, 0, 0xFF));
53 for (size_t i = 0; i < width * height; i++)
54 {
55 for (size_t b = 0; b < 4; b++)
56 {
57 if (alpha[b] != 0)
58 data[i * 4ull + b] = pad;
59 }
60 }
61}
62
63int TestShadowCaptureCompare(int argc, char* argv[])
64{
65 WINPR_UNUSED(argc);
66 WINPR_UNUSED(argv);
67
68#define WIDTH 64ul
69#define HEIGHT 48ull
70
71 BYTE surface[WIDTH * HEIGHT * 4ull] = WINPR_C_ARRAY_INIT;
72 BYTE capture[WIDTH * HEIGHT * 4ull] = WINPR_C_ARRAY_INIT;
73
74 /* surface format with padding, capture format with alpha, as the X11 backend has them */
75 const UINT32 pairs[][2] = { { PIXEL_FORMAT_BGRX32, PIXEL_FORMAT_BGRA32 },
76 { PIXEL_FORMAT_RGBX32, PIXEL_FORMAT_RGBA32 },
77 { PIXEL_FORMAT_XRGB32, PIXEL_FORMAT_ARGB32 },
78 { PIXEL_FORMAT_XBGR32, PIXEL_FORMAT_ABGR32 } };
79
80 for (size_t i = 0; i < ARRAYSIZE(pairs); i++)
81 {
82 const UINT32 surfaceFormat = pairs[i][0];
83 const UINT32 captureFormat = pairs[i][1];
84
85 for (int pad = 0; pad < 2; pad++)
86 {
87 if (!fill(surface, WIDTH, HEIGHT, surfaceFormat, 0xFF) ||
88 !fill(capture, WIDTH, HEIGHT, captureFormat, 0x00))
89 return -1;
90 /* X server images leave the alpha byte 0, the surface may hold either value */
91 set_padding(surface, WIDTH, HEIGHT, captureFormat, pad ? 0xFF : 0x00);
92 set_padding(capture, WIDTH, HEIGHT, captureFormat, 0x00);
93
94 if (!expect(surface, WIDTH, HEIGHT, capture, WIDTH, HEIGHT, "identical colours",
95 surfaceFormat, captureFormat, 0, nullptr))
96 return -1;
97
98 /* one pixel changes: only its 16x16 tile is reported */
99 BYTE* pixel = &capture[(20ull * WIDTH + 40ull) * 4ull];
100 pixel[0] ^= 0x80;
101 pixel[1] ^= 0x80;
102 pixel[2] ^= 0x80;
103 pixel[3] ^= 0x80;
104 const RECTANGLE_16 tile = { 32, 16, 48, 32 };
105 if (!expect(surface, WIDTH, HEIGHT, capture, WIDTH, HEIGHT, "one pixel changed",
106 surfaceFormat, captureFormat, 1, &tile))
107 return -1;
108 }
109 }
110
111 /* the same format keeps comparing every byte */
112 if (!fill(surface, WIDTH, HEIGHT, PIXEL_FORMAT_BGRA32, 0xFF) ||
113 !fill(capture, WIDTH, HEIGHT, PIXEL_FORMAT_BGRA32, 0xFF))
114 return -1;
115 if (!expect(surface, WIDTH, HEIGHT, capture, WIDTH, HEIGHT, "same format", PIXEL_FORMAT_BGRA32,
116 PIXEL_FORMAT_BGRA32, 0, nullptr))
117 return -1;
118 capture[3] = 0x00;
119 if (!expect(surface, WIDTH, HEIGHT, capture, WIDTH, HEIGHT, "same format, alpha changed",
120 PIXEL_FORMAT_BGRA32, PIXEL_FORMAT_BGRA32, 1, nullptr))
121 return -1;
122
123 return 0;
124}