FreeRDP
TestFreeRDPCodecInterleaved.c
1 
2 #include <freerdp/config.h>
3 
4 #include <math.h>
5 
6 #include <winpr/crt.h>
7 #include <winpr/print.h>
8 
9 #include <freerdp/freerdp.h>
10 #include <freerdp/codec/color.h>
11 #include <freerdp/codec/bitmap.h>
12 #include <freerdp/codec/interleaved.h>
13 #include <winpr/crypto.h>
14 #include <freerdp/utils/profiler.h>
15 
16 static BOOL run_encode_decode_single(UINT16 bpp, BITMAP_INTERLEAVED_CONTEXT* encoder,
17  BITMAP_INTERLEAVED_CONTEXT* decoder
18 #if defined(WITH_PROFILER)
19  ,
20  PROFILER* profiler_comp, PROFILER* profiler_decomp
21 #endif
22 )
23 {
24  BOOL rc2 = FALSE;
25  BOOL rc = 0;
26  const UINT32 w = 64;
27  const UINT32 h = 64;
28  const UINT32 x = 0;
29  const UINT32 y = 0;
30  const UINT32 format = PIXEL_FORMAT_RGBX32;
31  const UINT32 bstep = FreeRDPGetBytesPerPixel(format);
32  const size_t step = (13ULL + w) * 4ULL;
33  const size_t SrcSize = step * h;
34  const float maxDiff = 4.0f * ((bpp < 24) ? 2.0f : 1.0f);
35  UINT32 DstSize = SrcSize;
36  BYTE* pSrcData = calloc(1, SrcSize);
37  BYTE* pDstData = calloc(1, SrcSize);
38  BYTE* tmp = calloc(1, SrcSize);
39 
40  if (!pSrcData || !pDstData || !tmp)
41  goto fail;
42 
43  winpr_RAND(pSrcData, SrcSize);
44 
45  if (!bitmap_interleaved_context_reset(encoder) || !bitmap_interleaved_context_reset(decoder))
46  goto fail;
47 
48  PROFILER_ENTER(profiler_comp)
49  rc =
50  interleaved_compress(encoder, tmp, &DstSize, w, h, pSrcData, format, step, x, y, NULL, bpp);
51  PROFILER_EXIT(profiler_comp)
52 
53  if (!rc)
54  goto fail;
55 
56  PROFILER_ENTER(profiler_decomp)
57  rc = interleaved_decompress(decoder, tmp, DstSize, w, h, bpp, pDstData, format, step, x, y, w,
58  h, NULL);
59  PROFILER_EXIT(profiler_decomp)
60 
61  if (!rc)
62  goto fail;
63 
64  for (UINT32 i = 0; i < h; i++)
65  {
66  const BYTE* srcLine = &pSrcData[i * step];
67  const BYTE* dstLine = &pDstData[i * step];
68 
69  for (UINT32 j = 0; j < w; j++)
70  {
71  BYTE r = 0;
72  BYTE g = 0;
73  BYTE b = 0;
74  BYTE dr = 0;
75  BYTE dg = 0;
76  BYTE db = 0;
77  const UINT32 srcColor = FreeRDPReadColor(&srcLine[1ULL * j * bstep], format);
78  const UINT32 dstColor = FreeRDPReadColor(&dstLine[1ULL * j * bstep], format);
79  FreeRDPSplitColor(srcColor, format, &r, &g, &b, NULL, NULL);
80  FreeRDPSplitColor(dstColor, format, &dr, &dg, &db, NULL, NULL);
81 
82  if (fabsf((float)r - dr) > maxDiff)
83  goto fail;
84 
85  if (fabsf((float)g - dg) > maxDiff)
86  goto fail;
87 
88  if (fabsf((float)b - db) > maxDiff)
89  goto fail;
90  }
91  }
92 
93  rc2 = TRUE;
94 fail:
95  free(pSrcData);
96  free(pDstData);
97  free(tmp);
98  return rc2;
99 }
100 
101 static const char* get_profiler_name(BOOL encode, UINT16 bpp)
102 {
103  switch (bpp)
104  {
105  case 24:
106  if (encode)
107  return "interleaved_compress 24bpp";
108  else
109  return "interleaved_decompress 24bpp";
110 
111  case 16:
112  if (encode)
113  return "interleaved_compress 16bpp";
114  else
115  return "interleaved_decompress 16bpp";
116 
117  case 15:
118  if (encode)
119  return "interleaved_compress 15bpp";
120  else
121  return "interleaved_decompress 15bpp";
122 
123  default:
124  return "configuration error!";
125  }
126 }
127 
128 static BOOL run_encode_decode(UINT16 bpp, BITMAP_INTERLEAVED_CONTEXT* encoder,
129  BITMAP_INTERLEAVED_CONTEXT* decoder)
130 {
131  BOOL rc = FALSE;
132  PROFILER_DEFINE(profiler_comp)
133  PROFILER_DEFINE(profiler_decomp)
134  PROFILER_CREATE(profiler_comp, get_profiler_name(TRUE, bpp))
135  PROFILER_CREATE(profiler_decomp, get_profiler_name(FALSE, bpp))
136 
137  for (UINT32 x = 0; x < 50; x++)
138  {
139  if (!run_encode_decode_single(bpp, encoder, decoder
140 #if defined(WITH_PROFILER)
141  ,
142  profiler_comp, profiler_decomp
143 #endif
144  ))
145  goto fail;
146  }
147 
148  rc = TRUE;
149 fail:
150  PROFILER_PRINT_HEADER
151  PROFILER_PRINT(profiler_comp)
152  PROFILER_PRINT(profiler_decomp)
153  PROFILER_PRINT_FOOTER
154  PROFILER_FREE(profiler_comp)
155  PROFILER_FREE(profiler_decomp)
156  return rc;
157 }
158 
159 static BOOL TestColorConversion(void)
160 {
161  const UINT32 formats[] = { PIXEL_FORMAT_RGB15, PIXEL_FORMAT_BGR15, PIXEL_FORMAT_ABGR15,
162  PIXEL_FORMAT_ARGB15, PIXEL_FORMAT_BGR16, PIXEL_FORMAT_RGB16 };
163 
164  /* Check color conversion 15/16 -> 32bit maps to proper values */
165  for (UINT32 x = 0; x < ARRAYSIZE(formats); x++)
166  {
167  const UINT32 dstFormat = PIXEL_FORMAT_RGBA32;
168  const UINT32 format = formats[x];
169  const UINT32 colorLow = FreeRDPGetColor(format, 0, 0, 0, 255);
170  const UINT32 colorHigh = FreeRDPGetColor(format, 255, 255, 255, 255);
171  const UINT32 colorLow32 = FreeRDPConvertColor(colorLow, format, dstFormat, NULL);
172  const UINT32 colorHigh32 = FreeRDPConvertColor(colorHigh, format, dstFormat, NULL);
173  BYTE r = 0;
174  BYTE g = 0;
175  BYTE b = 0;
176  BYTE a = 0;
177  FreeRDPSplitColor(colorLow32, dstFormat, &r, &g, &b, &a, NULL);
178  if ((r != 0) || (g != 0) || (b != 0))
179  return FALSE;
180 
181  FreeRDPSplitColor(colorHigh32, dstFormat, &r, &g, &b, &a, NULL);
182  if ((r != 255) || (g != 255) || (b != 255))
183  return FALSE;
184  }
185 
186  return TRUE;
187 }
188 
189 int TestFreeRDPCodecInterleaved(int argc, char* argv[])
190 {
191  BITMAP_INTERLEAVED_CONTEXT* encoder = NULL;
192  BITMAP_INTERLEAVED_CONTEXT* decoder = NULL;
193  int rc = -1;
194  WINPR_UNUSED(argc);
195  WINPR_UNUSED(argv);
196  encoder = bitmap_interleaved_context_new(TRUE);
197  decoder = bitmap_interleaved_context_new(FALSE);
198 
199  if (!encoder || !decoder)
200  goto fail;
201 
202  if (!run_encode_decode(24, encoder, decoder))
203  goto fail;
204 
205  if (!run_encode_decode(16, encoder, decoder))
206  goto fail;
207 
208  if (!run_encode_decode(15, encoder, decoder))
209  goto fail;
210 
211  if (!TestColorConversion())
212  goto fail;
213 
214  rc = 0;
215 fail:
216  bitmap_interleaved_context_free(encoder);
217  bitmap_interleaved_context_free(decoder);
218  return rc;
219 }