FreeRDP
rfx_rlgr.c
1 
25 #include <freerdp/config.h>
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include <winpr/crt.h>
32 #include <winpr/print.h>
33 #include <winpr/sysinfo.h>
34 #include <winpr/bitstream.h>
35 #include <winpr/intrin.h>
36 
37 #include "rfx_bitstream.h"
38 
39 #include "rfx_rlgr.h"
40 
41 /* Constants used in RLGR1/RLGR3 algorithm */
42 #define KPMAX (80) /* max value for kp or krp */
43 #define LSGR (3) /* shift count to convert kp to k */
44 #define UP_GR (4) /* increase in kp after a zero run in RL mode */
45 #define DN_GR (6) /* decrease in kp after a nonzero symbol in RL mode */
46 #define UQ_GR (3) /* increase in kp after nonzero symbol in GR mode */
47 #define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */
48 
49 /* Returns the least number of bits required to represent a given value */
50 #define GetMinBits(_val, _nbits) \
51  do \
52  { \
53  UINT32 _v = (_val); \
54  (_nbits) = 0; \
55  while (_v) \
56  { \
57  _v >>= 1; \
58  (_nbits)++; \
59  } \
60  } while (0)
61 
62 /*
63  * Update the passed parameter and clamp it to the range [0, KPMAX]
64  * Return the value of parameter right-shifted by LSGR
65  */
66 #define UpdateParam(_param, _deltaP, _k) \
67  do \
68  { \
69  (_param) += (_deltaP); \
70  if ((_param) > KPMAX) \
71  (_param) = KPMAX; \
72  if ((_param) < 0) \
73  (_param) = 0; \
74  (_k) = ((_param) >> LSGR); \
75  } while (0)
76 
77 static BOOL g_LZCNT = FALSE;
78 
79 static INIT_ONCE rfx_rlgr_init_once = INIT_ONCE_STATIC_INIT;
80 
81 static BOOL CALLBACK rfx_rlgr_init(PINIT_ONCE once, PVOID param, PVOID* context)
82 {
83  g_LZCNT = IsProcessorFeaturePresentEx(PF_EX_LZCNT);
84  return TRUE;
85 }
86 
87 static INLINE UINT32 lzcnt_s(UINT32 x)
88 {
89  if (!x)
90  return 32;
91 
92  if (!g_LZCNT)
93  {
94  UINT32 y = 0;
95  UINT32 n = 32;
96  y = x >> 16;
97  if (y != 0)
98  {
99  WINPR_ASSERT(n >= 16);
100  n = n - 16;
101  x = y;
102  }
103  y = x >> 8;
104  if (y != 0)
105  {
106  WINPR_ASSERT(n >= 8);
107  n = n - 8;
108  x = y;
109  }
110  y = x >> 4;
111  if (y != 0)
112  {
113  WINPR_ASSERT(n >= 4);
114  n = n - 4;
115  x = y;
116  }
117  y = x >> 2;
118  if (y != 0)
119  {
120  WINPR_ASSERT(n >= 2);
121  n = n - 2;
122  x = y;
123  }
124  y = x >> 1;
125  if (y != 0)
126  {
127  WINPR_ASSERT(n >= 2);
128  return n - 2;
129  }
130 
131  WINPR_ASSERT(n >= x);
132  return n - x;
133  }
134 
135  return __lzcnt(x);
136 }
137 
138 int rfx_rlgr_decode(RLGR_MODE mode, const BYTE* WINPR_RESTRICT pSrcData, UINT32 SrcSize,
139  INT16* WINPR_RESTRICT pDstData, UINT32 rDstSize)
140 {
141  int vk = 0;
142  size_t run = 0;
143  int cnt = 0;
144  size_t size = 0;
145  size_t offset = 0;
146  INT16 mag = 0;
147  UINT32 k = 0;
148  INT32 kp = 0;
149  UINT32 kr = 0;
150  INT32 krp = 0;
151  UINT16 code = 0;
152  UINT32 sign = 0;
153  UINT32 nIdx = 0;
154  UINT32 val1 = 0;
155  UINT32 val2 = 0;
156  INT16* pOutput = NULL;
157  wBitStream* bs = NULL;
158  wBitStream s_bs = { 0 };
159  const SSIZE_T DstSize = rDstSize;
160 
161  InitOnceExecuteOnce(&rfx_rlgr_init_once, rfx_rlgr_init, NULL, NULL);
162 
163  k = 1;
164  kp = k << LSGR;
165 
166  kr = 1;
167  krp = kr << LSGR;
168 
169  if ((mode != RLGR1) && (mode != RLGR3))
170  mode = RLGR1;
171 
172  if (!pSrcData || !SrcSize)
173  return -1;
174 
175  if (!pDstData || !DstSize)
176  return -1;
177 
178  pOutput = pDstData;
179 
180  bs = &s_bs;
181 
182  BitStream_Attach(bs, pSrcData, SrcSize);
183  BitStream_Fetch(bs);
184 
185  while ((BitStream_GetRemainingLength(bs) > 0) && ((pOutput - pDstData) < DstSize))
186  {
187  if (k)
188  {
189  /* Run-Length (RL) Mode */
190 
191  run = 0;
192 
193  /* count number of leading 0s */
194 
195  cnt = lzcnt_s(bs->accumulator);
196 
197  size_t nbits = BitStream_GetRemainingLength(bs);
198 
199  if ((size_t)cnt > nbits)
200  cnt = (int)nbits;
201 
202  vk = cnt;
203 
204  while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
205  {
206  BitStream_Shift32(bs);
207 
208  cnt = lzcnt_s(bs->accumulator);
209 
210  nbits = BitStream_GetRemainingLength(bs);
211 
212  if ((size_t)cnt > nbits)
213  cnt = (int)nbits;
214 
215  vk += cnt;
216  }
217 
218  BitStream_Shift(bs, (vk % 32));
219 
220  if (BitStream_GetRemainingLength(bs) < 1)
221  break;
222 
223  BitStream_Shift(bs, 1);
224 
225  while (vk--)
226  {
227  const UINT32 add = (1 << k); /* add (1 << k) to run length */
228  run += add;
229 
230  /* update k, kp params */
231 
232  kp += UP_GR;
233 
234  if (kp > KPMAX)
235  kp = KPMAX;
236 
237  k = kp >> LSGR;
238  }
239 
240  /* next k bits contain run length remainder */
241 
242  if (BitStream_GetRemainingLength(bs) < k)
243  break;
244 
245  bs->mask = ((1 << k) - 1);
246  run += ((bs->accumulator >> (32 - k)) & bs->mask);
247  BitStream_Shift(bs, k);
248 
249  /* read sign bit */
250 
251  if (BitStream_GetRemainingLength(bs) < 1)
252  break;
253 
254  sign = (bs->accumulator & 0x80000000) ? 1 : 0;
255  BitStream_Shift(bs, 1);
256 
257  /* count number of leading 1s */
258 
259  cnt = lzcnt_s(~(bs->accumulator));
260 
261  nbits = BitStream_GetRemainingLength(bs);
262 
263  if ((size_t)cnt > nbits)
264  cnt = (int)nbits;
265 
266  vk = cnt;
267 
268  while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
269  {
270  BitStream_Shift32(bs);
271 
272  cnt = lzcnt_s(~(bs->accumulator));
273 
274  nbits = BitStream_GetRemainingLength(bs);
275 
276  if ((size_t)cnt > nbits)
277  cnt = (int)nbits;
278 
279  vk += cnt;
280  }
281 
282  BitStream_Shift(bs, (vk % 32));
283 
284  if (BitStream_GetRemainingLength(bs) < 1)
285  break;
286 
287  BitStream_Shift(bs, 1);
288 
289  /* next kr bits contain code remainder */
290 
291  if (BitStream_GetRemainingLength(bs) < kr)
292  break;
293 
294  bs->mask = ((1 << kr) - 1);
295  if (kr > 0)
296  code = (UINT16)((bs->accumulator >> (32 - kr)) & bs->mask);
297  else
298  code = 0;
299  BitStream_Shift(bs, kr);
300 
301  /* add (vk << kr) to code */
302 
303  code |= (vk << kr);
304 
305  if (!vk)
306  {
307  /* update kr, krp params */
308 
309  krp -= 2;
310 
311  if (krp < 0)
312  krp = 0;
313 
314  kr = krp >> LSGR;
315  }
316  else if (vk != 1)
317  {
318  /* update kr, krp params */
319 
320  krp += vk;
321 
322  if (krp > KPMAX)
323  krp = KPMAX;
324 
325  kr = krp >> LSGR;
326  }
327 
328  /* update k, kp params */
329 
330  kp -= DN_GR;
331 
332  if (kp < 0)
333  kp = 0;
334 
335  k = kp >> LSGR;
336 
337  /* compute magnitude from code */
338 
339  if (sign)
340  mag = ((INT16)(code + 1)) * -1;
341  else
342  mag = (INT16)(code + 1);
343 
344  /* write to output stream */
345 
346  offset = (pOutput - pDstData);
347  size = run;
348 
349  if ((offset + size) > rDstSize)
350  size = DstSize - offset;
351 
352  if (size)
353  {
354  ZeroMemory(pOutput, size * sizeof(INT16));
355  pOutput += size;
356  }
357 
358  if ((pOutput - pDstData) < DstSize)
359  {
360  *pOutput = mag;
361  pOutput++;
362  }
363  }
364  else
365  {
366  /* Golomb-Rice (GR) Mode */
367 
368  /* count number of leading 1s */
369 
370  cnt = lzcnt_s(~(bs->accumulator));
371 
372  size_t nbits = BitStream_GetRemainingLength(bs);
373 
374  if ((size_t)cnt > nbits)
375  cnt = (int)nbits;
376 
377  vk = cnt;
378 
379  while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
380  {
381  BitStream_Shift32(bs);
382 
383  cnt = lzcnt_s(~(bs->accumulator));
384 
385  nbits = BitStream_GetRemainingLength(bs);
386 
387  if ((size_t)cnt > nbits)
388  cnt = (int)nbits;
389 
390  vk += cnt;
391  }
392 
393  BitStream_Shift(bs, (vk % 32));
394 
395  if (BitStream_GetRemainingLength(bs) < 1)
396  break;
397 
398  BitStream_Shift(bs, 1);
399 
400  /* next kr bits contain code remainder */
401 
402  if (BitStream_GetRemainingLength(bs) < kr)
403  break;
404 
405  bs->mask = ((1 << kr) - 1);
406  if (kr > 0)
407  code = (UINT16)((bs->accumulator >> (32 - kr)) & bs->mask);
408  else
409  code = 0;
410  BitStream_Shift(bs, kr);
411 
412  /* add (vk << kr) to code */
413 
414  code |= (vk << kr);
415 
416  if (!vk)
417  {
418  /* update kr, krp params */
419 
420  krp -= 2;
421 
422  if (krp < 0)
423  krp = 0;
424 
425  kr = krp >> LSGR;
426  }
427  else if (vk != 1)
428  {
429  /* update kr, krp params */
430 
431  krp += vk;
432 
433  if (krp > KPMAX)
434  krp = KPMAX;
435 
436  kr = krp >> LSGR;
437  }
438 
439  if (mode == RLGR1) /* RLGR1 */
440  {
441  if (!code)
442  {
443  /* update k, kp params */
444 
445  kp += UQ_GR;
446 
447  if (kp > KPMAX)
448  kp = KPMAX;
449 
450  k = kp >> LSGR;
451 
452  mag = 0;
453  }
454  else
455  {
456  /* update k, kp params */
457 
458  kp -= DQ_GR;
459 
460  if (kp < 0)
461  kp = 0;
462 
463  k = kp >> LSGR;
464 
465  /*
466  * code = 2 * mag - sign
467  * sign + code = 2 * mag
468  */
469 
470  if (code & 1)
471  mag = ((INT16)((code + 1) >> 1)) * -1;
472  else
473  mag = (INT16)(code >> 1);
474  }
475 
476  if ((pOutput - pDstData) < DstSize)
477  {
478  *pOutput = mag;
479  pOutput++;
480  }
481  }
482  else if (mode == RLGR3) /* RLGR3 */
483  {
484  nIdx = 0;
485 
486  if (code)
487  {
488  mag = (UINT32)code;
489  nIdx = 32 - lzcnt_s(mag);
490  }
491 
492  if (BitStream_GetRemainingLength(bs) < nIdx)
493  break;
494 
495  bs->mask = ((1 << nIdx) - 1);
496  if (nIdx > 0)
497  val1 = ((bs->accumulator >> (32 - nIdx)) & bs->mask);
498  else
499  val1 = 0;
500  BitStream_Shift(bs, nIdx);
501 
502  val2 = code - val1;
503 
504  if (val1 && val2)
505  {
506  /* update k, kp params */
507 
508  kp -= (2 * DQ_GR);
509 
510  if (kp < 0)
511  kp = 0;
512 
513  k = kp >> LSGR;
514  }
515  else if (!val1 && !val2)
516  {
517  /* update k, kp params */
518 
519  kp += (2 * UQ_GR);
520 
521  if (kp > KPMAX)
522  kp = KPMAX;
523 
524  k = kp >> LSGR;
525  }
526 
527  if (val1 & 1)
528  mag = ((INT16)((val1 + 1) >> 1)) * -1;
529  else
530  mag = (INT16)(val1 >> 1);
531 
532  if ((pOutput - pDstData) < DstSize)
533  {
534  *pOutput = mag;
535  pOutput++;
536  }
537 
538  if (val2 & 1)
539  mag = ((INT16)((val2 + 1) >> 1)) * -1;
540  else
541  mag = (INT16)(val2 >> 1);
542 
543  if ((pOutput - pDstData) < DstSize)
544  {
545  *pOutput = mag;
546  pOutput++;
547  }
548  }
549  }
550  }
551 
552  offset = (pOutput - pDstData);
553 
554  if (offset < rDstSize)
555  {
556  size = DstSize - offset;
557  ZeroMemory(pOutput, size * 2);
558  pOutput += size;
559  }
560 
561  offset = (pOutput - pDstData);
562 
563  if ((DstSize < 0) || (offset != (size_t)DstSize))
564  return -1;
565 
566  return 1;
567 }
568 
569 /* Returns the next coefficient (a signed int) to encode, from the input stream */
570 #define GetNextInput(_n) \
571  do \
572  { \
573  if (data_size > 0) \
574  { \
575  (_n) = *data++; \
576  data_size--; \
577  } \
578  else \
579  { \
580  (_n) = 0; \
581  } \
582  } while (0)
583 
584 /* Emit bitPattern to the output bitstream */
585 #define OutputBits(numBits, bitPattern) rfx_bitstream_put_bits(bs, bitPattern, numBits)
586 
587 /* Emit a bit (0 or 1), count number of times, to the output bitstream */
588 #define OutputBit(count, bit) \
589  do \
590  { \
591  UINT16 _b = ((bit) ? 0xFFFF : 0); \
592  int _c = (count); \
593  for (; _c > 0; _c -= 16) \
594  rfx_bitstream_put_bits(bs, _b, (_c > 16 ? 16 : _c)); \
595  } while (0)
596 
597 /* Converts the input value to (2 * abs(input) - sign(input)), where sign(input) = (input < 0 ? 1 :
598  * 0) and returns it */
599 #define Get2MagSign(input) ((input) >= 0 ? 2 * (input) : -2 * (input)-1)
600 
601 /* Outputs the Golomb/Rice encoding of a non-negative integer */
602 #define CodeGR(krp, val) rfx_rlgr_code_gr(bs, krp, val)
603 
604 static void rfx_rlgr_code_gr(RFX_BITSTREAM* bs, int* krp, UINT32 val)
605 {
606  int kr = *krp >> LSGR;
607 
608  /* unary part of GR code */
609 
610  UINT32 vk = (val) >> kr;
611  OutputBit(vk, 1);
612  OutputBit(1, 0);
613 
614  /* remainder part of GR code, if needed */
615  if (kr)
616  {
617  OutputBits(kr, val & ((1 << kr) - 1));
618  }
619 
620  /* update krp, only if it is not equal to 1 */
621  if (vk == 0)
622  {
623  UpdateParam(*krp, -2, kr);
624  }
625  else if (vk > 1)
626  {
627  UpdateParam(*krp, vk, kr);
628  }
629 }
630 
631 int rfx_rlgr_encode(RLGR_MODE mode, const INT16* WINPR_RESTRICT data, UINT32 data_size,
632  BYTE* WINPR_RESTRICT buffer, UINT32 buffer_size)
633 {
634  int k = 0;
635  int kp = 0;
636  int krp = 0;
637  RFX_BITSTREAM* bs = NULL;
638  int processed_size = 0;
639 
640  if (!(bs = (RFX_BITSTREAM*)winpr_aligned_calloc(1, sizeof(RFX_BITSTREAM), 32)))
641  return 0;
642 
643  rfx_bitstream_attach(bs, buffer, buffer_size);
644 
645  /* initialize the parameters */
646  k = 1;
647  kp = 1 << LSGR;
648  krp = 1 << LSGR;
649 
650  /* process all the input coefficients */
651  while (data_size > 0)
652  {
653  int input = 0;
654 
655  if (k)
656  {
657  int numZeros = 0;
658  int runmax = 0;
659  int sign = 0;
660 
661  /* RUN-LENGTH MODE */
662 
663  /* collect the run of zeros in the input stream */
664  numZeros = 0;
665  GetNextInput(input);
666  while (input == 0 && data_size > 0)
667  {
668  numZeros++;
669  GetNextInput(input);
670  }
671 
672  // emit output zeros
673  runmax = 1 << k;
674  while (numZeros >= runmax)
675  {
676  OutputBit(1, 0); /* output a zero bit */
677  numZeros -= runmax;
678  UpdateParam(kp, UP_GR, k); /* update kp, k */
679  runmax = 1 << k;
680  }
681 
682  /* output a 1 to terminate runs */
683  OutputBit(1, 1);
684 
685  /* output the remaining run length using k bits */
686  OutputBits(k, numZeros);
687 
688  /* note: when we reach here and the last byte being encoded is 0, we still
689  need to output the last two bits, otherwise mstsc will crash */
690 
691  /* encode the nonzero value using GR coding */
692  const UINT32 mag =
693  (UINT32)(input < 0 ? -input : input); /* absolute value of input coefficient */
694  sign = (input < 0 ? 1 : 0); /* sign of input coefficient */
695 
696  OutputBit(1, sign); /* output the sign bit */
697  CodeGR(&krp, mag ? mag - 1 : 0); /* output GR code for (mag - 1) */
698 
699  UpdateParam(kp, -DN_GR, k);
700  }
701  else
702  {
703  /* GOLOMB-RICE MODE */
704 
705  if (mode == RLGR1)
706  {
707  UINT32 twoMs = 0;
708 
709  /* RLGR1 variant */
710 
711  /* convert input to (2*magnitude - sign), encode using GR code */
712  GetNextInput(input);
713  twoMs = Get2MagSign(input);
714  CodeGR(&krp, twoMs);
715 
716  /* update k, kp */
717  /* NOTE: as of Aug 2011, the algorithm is still wrongly documented
718  and the update direction is reversed */
719  if (twoMs)
720  {
721  UpdateParam(kp, -DQ_GR, k);
722  }
723  else
724  {
725  UpdateParam(kp, UQ_GR, k);
726  }
727  }
728  else /* mode == RLGR3 */
729  {
730  UINT32 twoMs1 = 0;
731  UINT32 twoMs2 = 0;
732  UINT32 sum2Ms = 0;
733  UINT32 nIdx = 0;
734 
735  /* RLGR3 variant */
736 
737  /* convert the next two input values to (2*magnitude - sign) and */
738  /* encode their sum using GR code */
739 
740  GetNextInput(input);
741  twoMs1 = Get2MagSign(input);
742  GetNextInput(input);
743  twoMs2 = Get2MagSign(input);
744  sum2Ms = twoMs1 + twoMs2;
745 
746  CodeGR(&krp, sum2Ms);
747 
748  /* encode binary representation of the first input (twoMs1). */
749  GetMinBits(sum2Ms, nIdx);
750  OutputBits(nIdx, twoMs1);
751 
752  /* update k,kp for the two input values */
753 
754  if (twoMs1 && twoMs2)
755  {
756  UpdateParam(kp, -2 * DQ_GR, k);
757  }
758  else if (!twoMs1 && !twoMs2)
759  {
760  UpdateParam(kp, 2 * UQ_GR, k);
761  }
762  }
763  }
764  }
765 
766  rfx_bitstream_flush(bs);
767  processed_size = rfx_bitstream_get_processed_bytes(bs);
768  winpr_aligned_free(bs);
769 
770  return processed_size;
771 }