FreeRDP
TestFreeRDPCodecCopy.c
1 
2 #include <math.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 
7 #include <winpr/sysinfo.h>
8 
9 #include <freerdp/freerdp.h>
10 #include <freerdp/codec/color.h>
11 
12 #define TEST_RUNS 2
13 
14 static BOOL TestFreeRDPImageCopy(UINT32 w, UINT32 h, UINT32 srcFormat, UINT32 dstFormat,
15  size_t runs)
16 {
17  BOOL rc = FALSE;
18  const size_t sbpp = FreeRDPGetBytesPerPixel(srcFormat);
19  const size_t dbpp = FreeRDPGetBytesPerPixel(dstFormat);
20  const size_t srcStep = w * sbpp;
21  const size_t dstStep = w * dbpp;
22  char* src = calloc(h, srcStep);
23  char* dst = calloc(h, dstStep);
24  if (!src || !dst)
25  goto fail;
26 
27  for (size_t x = 0; x < runs; x++)
28  {
29  winpr_RAND_pseudo(src, h * srcStep);
30  const UINT64 start = winpr_GetUnixTimeNS();
31  rc = freerdp_image_copy(dst, dstFormat, dstStep, 0, 0, w, h, src, srcFormat, srcStep, 0, 0,
32  NULL, 0);
33  const UINT64 end = winpr_GetUnixTimeNS();
34 
35  double ms = end - start;
36  ms /= 1000000.0;
37 
38  (void)fprintf(stdout,
39  "[%s] copied %" PRIu32 "x%" PRIu32 " [%-20s] -> [%-20s] in %lf ms [%s]\n",
40  __func__, w, h, FreeRDPGetColorFormatName(srcFormat),
41  FreeRDPGetColorFormatName(dstFormat), ms, rc ? "success" : "failure");
42  if (!rc)
43  break;
44  }
45 
46 fail:
47  free(src);
48  free(dst);
49  return rc;
50 }
51 
52 static BOOL TestFreeRDPImageCopy_no_overlap(UINT32 w, UINT32 h, UINT32 srcFormat, UINT32 dstFormat,
53  size_t runs)
54 {
55  BOOL rc = FALSE;
56  const size_t sbpp = FreeRDPGetBytesPerPixel(srcFormat);
57  const size_t dbpp = FreeRDPGetBytesPerPixel(dstFormat);
58  const size_t srcStep = w * sbpp;
59  const size_t dstStep = w * dbpp;
60  char* src = calloc(h, srcStep);
61  char* dst = calloc(h, dstStep);
62  if (!src || !dst)
63  goto fail;
64 
65  for (size_t x = 0; x < runs; x++)
66  {
67  winpr_RAND_pseudo(src, h * srcStep);
68  const UINT64 start = winpr_GetUnixTimeNS();
69  rc = freerdp_image_copy_no_overlap(dst, dstFormat, dstStep, 0, 0, w, h, src, srcFormat,
70  srcStep, 0, 0, NULL, 0);
71  const UINT64 end = winpr_GetUnixTimeNS();
72 
73  double ms = end - start;
74  ms /= 1000000.0;
75 
76  (void)fprintf(stdout,
77  "[%s] copied %" PRIu32 "x%" PRIu32 " [%-20s] -> [%-20s] in %lf ms [%s]\n",
78  __func__, w, h, FreeRDPGetColorFormatName(srcFormat),
79  FreeRDPGetColorFormatName(dstFormat), ms, rc ? "success" : "failure");
80  if (!rc)
81  break;
82  }
83 
84 fail:
85  free(src);
86  free(dst);
87  return rc;
88 }
89 int TestFreeRDPCodecCopy(int argc, char* argv[])
90 {
91  WINPR_UNUSED(argc);
92  WINPR_UNUSED(argv);
93 
94  UINT32 width = 192;
95  UINT32 height = 108;
96  const UINT32 formats[] = {
97  PIXEL_FORMAT_ABGR15, PIXEL_FORMAT_ARGB15, PIXEL_FORMAT_BGR15, PIXEL_FORMAT_BGR16,
98  PIXEL_FORMAT_BGR24, PIXEL_FORMAT_RGB15, PIXEL_FORMAT_RGB16, PIXEL_FORMAT_RGB24,
99  PIXEL_FORMAT_ABGR32, PIXEL_FORMAT_ARGB32, PIXEL_FORMAT_XBGR32, PIXEL_FORMAT_XRGB32,
100  PIXEL_FORMAT_BGRA32, PIXEL_FORMAT_RGBA32, PIXEL_FORMAT_BGRX32, PIXEL_FORMAT_RGBX32,
101  };
102 
103  if (argc == 3)
104  {
105  errno = 0;
106  width = strtoul(argv[1], NULL, 0);
107  height = strtoul(argv[2], NULL, 0);
108  if ((errno != 0) || (width == 0) || (height == 0))
109  {
110  char buffer[128] = { 0 };
111  (void)fprintf(stderr, "%s failed: width=%" PRIu32 ", height=%" PRIu32 ", errno=%s\n",
112  __func__, width, height, winpr_strerror(errno, buffer, sizeof(buffer)));
113  return -1;
114  }
115  }
116  for (size_t x = 0; x < ARRAYSIZE(formats); x++)
117  {
118  const UINT32 SrcFormat = formats[x];
119  for (size_t y = 0; y < ARRAYSIZE(formats); y++)
120  {
121  const UINT32 DstFormat = formats[y];
122  if (!TestFreeRDPImageCopy(width, height, SrcFormat, DstFormat, TEST_RUNS))
123  return -1;
124  if (!TestFreeRDPImageCopy_no_overlap(width, height, SrcFormat, DstFormat, TEST_RUNS))
125  return -1;
126  }
127  }
128 
129  return 0;
130 }