FreeRDP
Loading...
Searching...
No Matches
TestClipboardFormats.c
1
2#include <winpr/crt.h>
3#include <winpr/print.h>
4#include <winpr/image.h>
5#include <winpr/clipboard.h>
6#include <winpr/stream.h>
7#include <winpr/user.h>
8
9static BOOL test_dib_to_bmp(const BYTE* dib, size_t dibSize, size_t expectedOffset)
10{
11 BOOL rc = FALSE;
12
13 wClipboard* clipboard = ClipboardCreate();
14 if (!clipboard)
15 return FALSE;
16
17 const UINT32 bmpId = ClipboardRegisterFormat(clipboard, "image/bmp");
18 if ((bmpId == 0) || (dibSize > UINT32_MAX) ||
19 !ClipboardSetData(clipboard, CF_DIB, dib, (UINT32)dibSize))
20 goto fail;
21
22 UINT32 bmpSize = 0;
23 BYTE* bmp = ClipboardGetData(clipboard, bmpId, &bmpSize);
24 if (!bmp)
25 goto fail;
26
27 wStream bmpBuffer = WINPR_C_ARRAY_INIT;
28 wStream* s = Stream_StaticConstInit(&bmpBuffer, bmp, bmpSize);
29 if (!s || (bmpSize < sizeof(WINPR_BITMAP_FILE_HEADER)))
30 goto fail_bmp;
31
32 Stream_Seek(s, 10);
33 UINT32 bitmapOffset = 0;
34 Stream_Read_UINT32(s, bitmapOffset);
35 if ((bitmapOffset != expectedOffset) ||
36 (bmpSize != sizeof(WINPR_BITMAP_FILE_HEADER) + dibSize) ||
37 (memcmp(&bmp[sizeof(WINPR_BITMAP_FILE_HEADER)], dib, dibSize) != 0))
38 goto fail_bmp;
39
40 /* The synthesized BMP must also be readable by the image conversion code. */
41 wImage* image = winpr_image_new();
42 if (!image)
43 goto fail_bmp;
44 rc = (winpr_image_read_buffer(image, bmp, bmpSize) > 0);
45 winpr_image_free(image, TRUE);
46
47fail_bmp:
48 free(bmp);
49fail:
50 ClipboardDestroy(clipboard);
51 return rc;
52}
53
54static void write_dib_info_header(wStream* s, UINT32 size, UINT16 bpp, UINT32 compression)
55{
56 WINPR_ASSERT(s);
57
58 Stream_Write_UINT32(s, size);
59 Stream_Write_INT32(s, 1); /* width */
60 Stream_Write_INT32(s, 1); /* height */
61 Stream_Write_UINT16(s, 1); /* planes */
62 Stream_Write_UINT16(s, bpp);
63 Stream_Write_UINT32(s, compression);
64 Stream_Write_UINT32(s, 4); /* image size */
65 Stream_Zero(s, 16); /* resolution and palette metadata */
66}
67
68static BOOL test_dib_offsets(void)
69{
70 BYTE v4[sizeof(BITMAPV4HEADER) + 4] = WINPR_C_ARRAY_INIT;
71 wStream sbuffer = WINPR_C_ARRAY_INIT;
72 wStream* s = Stream_StaticInit(&sbuffer, v4, sizeof(v4));
73 if (!s)
74 return FALSE;
75 write_dib_info_header(s, sizeof(BITMAPV4HEADER), 32, BI_BITFIELDS);
76
77 Stream_Write_UINT32(s, 0x00FF0000); /* red mask */
78 Stream_Write_UINT32(s, 0x0000FF00); /* green mask */
79 Stream_Write_UINT32(s, 0x000000FF); /* blue mask */
80 Stream_Write_UINT32(s, 0xFF000000); /* alpha mask */
81 Stream_Zero(s, sizeof(BITMAPV4HEADER) - Stream_GetPosition(s));
82 Stream_Write_UINT32(s, 0xFF123456); /* pixel */
83 if (!test_dib_to_bmp(v4, sizeof(v4), sizeof(WINPR_BITMAP_FILE_HEADER) + sizeof(BITMAPV4HEADER)))
84 return FALSE;
85
86 BYTE bitfields[sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD) + 4] = WINPR_C_ARRAY_INIT;
87 s = Stream_StaticInit(&sbuffer, bitfields, sizeof(bitfields));
88 if (!s)
89 return FALSE;
90 write_dib_info_header(s, sizeof(BITMAPINFOHEADER), 32, BI_BITFIELDS);
91 Stream_Write_UINT32(s, 0x00FF0000); /* red mask */
92 Stream_Write_UINT32(s, 0x0000FF00); /* green mask */
93 Stream_Write_UINT32(s, 0x000000FF); /* blue mask */
94 Stream_Write_UINT32(s, 0xFF123456); /* pixel */
95 if (!test_dib_to_bmp(bitfields, sizeof(bitfields),
97 3 * sizeof(DWORD)))
98 return FALSE;
99
100 BYTE paletted[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD) + 4] = WINPR_C_ARRAY_INIT;
101 s = Stream_StaticInit(&sbuffer, paletted, sizeof(paletted));
102 if (!s)
103 return FALSE;
104 write_dib_info_header(s, sizeof(BITMAPINFOHEADER), 8, BI_RGB);
105 Stream_Zero(s, 256 * sizeof(RGBQUAD));
106 Stream_Write_UINT32(s, 0); /* pixel row */
107 return test_dib_to_bmp(paletted, sizeof(paletted),
109 256 * sizeof(RGBQUAD));
110}
111
112int TestClipboardFormats(int argc, char* argv[])
113{
114 int rc = -1;
115 UINT32 count = 0;
116 UINT32* pFormatIds = nullptr;
117 const char* formatName = nullptr;
118 wClipboard* clipboard = nullptr;
119 UINT32 utf8StringFormatId = 0;
120
121 WINPR_UNUSED(argc);
122 WINPR_UNUSED(argv);
123
124 clipboard = ClipboardCreate();
125 if (!clipboard)
126 return -1;
127 if (!test_dib_offsets())
128 goto fail;
129
130 const char* mime_types[] = { "text/html", "text/html", "image/bmp",
131 "image/png", "image/webp", "image/jpeg" };
132 for (size_t x = 0; x < ARRAYSIZE(mime_types); x++)
133 {
134 const char* mime = mime_types[x];
135 UINT32 id = ClipboardRegisterFormat(clipboard, mime);
136 (void)fprintf(stderr, "ClipboardRegisterFormat(%s) -> 0x%08" PRIx32 "\n", mime, id);
137 if (id == 0)
138 goto fail;
139 }
140
141 utf8StringFormatId = ClipboardRegisterFormat(clipboard, "UTF8_STRING");
142 pFormatIds = nullptr;
143 count = ClipboardGetRegisteredFormatIds(clipboard, &pFormatIds);
144
145 for (UINT32 index = 0; index < count; index++)
146 {
147 UINT32 formatId = pFormatIds[index];
148 formatName = ClipboardGetFormatName(clipboard, formatId);
149 (void)fprintf(stderr, "Format: 0x%08" PRIX32 " %s\n", formatId, formatName);
150 }
151
152 free(pFormatIds);
153
154 if (1)
155 {
156 BOOL bSuccess = 0;
157 UINT32 SrcSize = 0;
158 UINT32 DstSize = 0;
159 const char pSrcData[] = "this is a test string";
160 char* pDstData = nullptr;
161
162 SrcSize = (UINT32)(strnlen(pSrcData, ARRAYSIZE(pSrcData)) + 1);
163 bSuccess = ClipboardSetData(clipboard, utf8StringFormatId, pSrcData, SrcSize);
164 (void)fprintf(stderr, "ClipboardSetData: %" PRId32 "\n", bSuccess);
165 DstSize = 0;
166 pDstData = (char*)ClipboardGetData(clipboard, utf8StringFormatId, &DstSize);
167 (void)fprintf(stderr, "ClipboardGetData: %s\n", pDstData);
168 free(pDstData);
169 }
170
171 if (1)
172 {
173 UINT32 DstSize = 0;
174 char* pSrcData = nullptr;
175 WCHAR* pDstData = nullptr;
176 DstSize = 0;
177 pDstData = (WCHAR*)ClipboardGetData(clipboard, CF_UNICODETEXT, &DstSize);
178 pSrcData = ConvertWCharNToUtf8Alloc(pDstData, DstSize / sizeof(WCHAR), nullptr);
179
180 (void)fprintf(stderr, "ClipboardGetData (synthetic): %s\n", pSrcData);
181 free(pDstData);
182 free(pSrcData);
183 }
184
185 pFormatIds = nullptr;
186 count = ClipboardGetFormatIds(clipboard, &pFormatIds);
187
188 for (UINT32 index = 0; index < count; index++)
189 {
190 UINT32 formatId = pFormatIds[index];
191 formatName = ClipboardGetFormatName(clipboard, formatId);
192 (void)fprintf(stderr, "Format: 0x%08" PRIX32 " %s\n", formatId, formatName);
193 }
194
195 if (1)
196 {
197 const char* name = TEST_CLIP_BMP;
198 BOOL bSuccess = FALSE;
199 UINT32 idBmp = ClipboardRegisterFormat(clipboard, "image/bmp");
200
201 wImage* img = winpr_image_new();
202 if (!img)
203 goto fail;
204
205 if (winpr_image_read(img, name) <= 0)
206 {
207 winpr_image_free(img, TRUE);
208 goto fail;
209 }
210
211 size_t bmpsize = 0;
212 void* data = winpr_image_write_buffer(img, WINPR_IMAGE_BITMAP, &bmpsize);
213 bSuccess = ClipboardSetData(clipboard, idBmp, data, bmpsize);
214 (void)fprintf(stderr, "ClipboardSetData: %" PRId32 "\n", bSuccess);
215
216 free(data);
217 winpr_image_free(img, TRUE);
218 if (!bSuccess)
219 goto fail;
220
221 {
222 UINT32 id = CF_DIB;
223
224 UINT32 DstSize = 0;
225 void* pDstData = ClipboardGetData(clipboard, id, &DstSize);
226 (void)fprintf(stderr, "ClipboardGetData: [CF_DIB] %p [%" PRIu32 "]\n", pDstData,
227 DstSize);
228 if (!pDstData)
229 goto fail;
230 bSuccess = ClipboardSetData(clipboard, id, pDstData, DstSize);
231 free(pDstData);
232 if (!bSuccess)
233 goto fail;
234 }
235 {
236 const uint32_t id = ClipboardGetFormatId(clipboard, "HTML Format");
237 UINT32 DstSize = 0;
238 void* pDstData = ClipboardGetData(clipboard, id, &DstSize);
239 if (!pDstData)
240 goto fail;
241 {
242 FILE* fp = fopen("test.html", "w");
243 if (fp)
244 {
245 (void)fwrite(pDstData, 1, DstSize, fp);
246 (void)fclose(fp);
247 }
248 }
249 free(pDstData);
250 }
251 {
252 UINT32 id = ClipboardRegisterFormat(clipboard, "image/bmp");
253
254 UINT32 DstSize = 0;
255 void* pDstData = ClipboardGetData(clipboard, id, &DstSize);
256 (void)fprintf(stderr, "ClipboardGetData: [image/bmp] %p [%" PRIu32 "]\n", pDstData,
257 DstSize);
258 if (!pDstData)
259 goto fail;
260 free(pDstData);
261 if (DstSize != bmpsize)
262 goto fail;
263 }
264
265#if defined(WINPR_UTILS_IMAGE_PNG)
266 {
267 UINT32 id = ClipboardRegisterFormat(clipboard, "image/png");
268
269 UINT32 DstSize = 0;
270 void* pDstData = ClipboardGetData(clipboard, id, &DstSize);
271 (void)fprintf(stderr, "ClipboardGetData: [image/png] %p\n", pDstData);
272 if (!pDstData)
273 goto fail;
274 free(pDstData);
275 }
276 {
277 const char* name = TEST_CLIP_PNG;
278 BOOL bSuccess = FALSE;
279 UINT32 idBmp = ClipboardRegisterFormat(clipboard, "image/png");
280
281 wImage* img = winpr_image_new();
282 if (!img)
283 goto fail;
284
285 if (winpr_image_read(img, name) <= 0)
286 {
287 winpr_image_free(img, TRUE);
288 goto fail;
289 }
290
291 size_t bmpsize = 0;
292 void* data = winpr_image_write_buffer(img, WINPR_IMAGE_PNG, &bmpsize);
293 bSuccess = ClipboardSetData(clipboard, idBmp, data, bmpsize);
294 (void)fprintf(stderr, "ClipboardSetData: %" PRId32 "\n", bSuccess);
295
296 free(data);
297 winpr_image_free(img, TRUE);
298 if (!bSuccess)
299 goto fail;
300 }
301 {
302 UINT32 id = CF_DIB;
303
304 UINT32 DstSize = 0;
305 void* pDstData = ClipboardGetData(clipboard, id, &DstSize);
306 (void)fprintf(stderr, "ClipboardGetData: [CF_DIB] %p [%" PRIu32 "]\n", pDstData,
307 DstSize);
308 if (!pDstData)
309 goto fail;
310 bSuccess = ClipboardSetData(clipboard, id, pDstData, DstSize);
311 free(pDstData);
312 if (!bSuccess)
313 goto fail;
314 }
315#endif
316
317#if defined(WINPR_UTILS_IMAGE_WEBP)
318 {
319 UINT32 id = ClipboardRegisterFormat(clipboard, "image/webp");
320
321 UINT32 DstSize = 0;
322 void* pDstData = ClipboardGetData(clipboard, id, &DstSize);
323 (void)fprintf(stderr, "ClipboardGetData: [image/webp] %p\n", pDstData);
324 if (!pDstData)
325 goto fail;
326 free(pDstData);
327 }
328#endif
329
330#if defined(WINPR_UTILS_IMAGE_JPEG)
331 {
332 UINT32 id = ClipboardRegisterFormat(clipboard, "image/jpeg");
333
334 UINT32 DstSize = 0;
335 void* pDstData = ClipboardGetData(clipboard, id, &DstSize);
336 (void)fprintf(stderr, "ClipboardGetData: [image/jpeg] %p\n", pDstData);
337 if (!pDstData)
338 goto fail;
339 free(pDstData);
340 }
341#endif
342 }
343
344 rc = 0;
345
346fail:
347 free(pFormatIds);
348 ClipboardDestroy(clipboard);
349 return rc;
350}