25 #include <freerdp/config.h>
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>
37 #include "rfx_bitstream.h"
50 #define GetMinBits(_val, _nbits) \
66 #define UpdateParam(_param, _deltaP, _k) \
69 (_param) += (_deltaP); \
70 if ((_param) > KPMAX) \
74 (_k) = ((_param) >> LSGR); \
77 static BOOL g_LZCNT = FALSE;
79 static INIT_ONCE rfx_rlgr_init_once = INIT_ONCE_STATIC_INIT;
81 static BOOL CALLBACK rfx_rlgr_init(
PINIT_ONCE once, PVOID param, PVOID* context)
83 g_LZCNT = IsProcessorFeaturePresentEx(PF_EX_LZCNT);
87 static INLINE UINT32 lzcnt_s(UINT32 x)
99 WINPR_ASSERT(n >= 16);
106 WINPR_ASSERT(n >= 8);
113 WINPR_ASSERT(n >= 4);
120 WINPR_ASSERT(n >= 2);
127 WINPR_ASSERT(n >= 2);
131 WINPR_ASSERT(n >= x);
138 int rfx_rlgr_decode(RLGR_MODE mode,
const BYTE* WINPR_RESTRICT pSrcData, UINT32 SrcSize,
139 INT16* WINPR_RESTRICT pDstData, UINT32 rDstSize)
156 INT16* pOutput = NULL;
159 const SSIZE_T DstSize = rDstSize;
161 InitOnceExecuteOnce(&rfx_rlgr_init_once, rfx_rlgr_init, NULL, NULL);
169 if ((mode != RLGR1) && (mode != RLGR3))
172 if (!pSrcData || !SrcSize)
175 if (!pDstData || !DstSize)
182 BitStream_Attach(bs, pSrcData, SrcSize);
185 while ((BitStream_GetRemainingLength(bs) > 0) && ((pOutput - pDstData) < DstSize))
195 cnt = lzcnt_s(bs->accumulator);
197 size_t nbits = BitStream_GetRemainingLength(bs);
199 if ((
size_t)cnt > nbits)
204 while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
206 BitStream_Shift32(bs);
208 cnt = lzcnt_s(bs->accumulator);
210 nbits = BitStream_GetRemainingLength(bs);
212 if ((
size_t)cnt > nbits)
218 BitStream_Shift(bs, (vk % 32));
220 if (BitStream_GetRemainingLength(bs) < 1)
223 BitStream_Shift(bs, 1);
227 const UINT32 add = (1 << k);
242 if (BitStream_GetRemainingLength(bs) < k)
245 bs->mask = ((1 << k) - 1);
246 run += ((bs->accumulator >> (32 - k)) & bs->mask);
247 BitStream_Shift(bs, k);
251 if (BitStream_GetRemainingLength(bs) < 1)
254 sign = (bs->accumulator & 0x80000000) ? 1 : 0;
255 BitStream_Shift(bs, 1);
259 cnt = lzcnt_s(~(bs->accumulator));
261 nbits = BitStream_GetRemainingLength(bs);
263 if ((
size_t)cnt > nbits)
268 while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
270 BitStream_Shift32(bs);
272 cnt = lzcnt_s(~(bs->accumulator));
274 nbits = BitStream_GetRemainingLength(bs);
276 if ((
size_t)cnt > nbits)
282 BitStream_Shift(bs, (vk % 32));
284 if (BitStream_GetRemainingLength(bs) < 1)
287 BitStream_Shift(bs, 1);
291 if (BitStream_GetRemainingLength(bs) < kr)
294 bs->mask = ((1 << kr) - 1);
296 code = (UINT16)((bs->accumulator >> (32 - kr)) & bs->mask);
299 BitStream_Shift(bs, kr);
340 mag = ((INT16)(code + 1)) * -1;
342 mag = (INT16)(code + 1);
346 offset = (pOutput - pDstData);
349 if ((offset + size) > rDstSize)
350 size = DstSize - offset;
354 ZeroMemory(pOutput, size *
sizeof(INT16));
358 if ((pOutput - pDstData) < DstSize)
370 cnt = lzcnt_s(~(bs->accumulator));
372 size_t nbits = BitStream_GetRemainingLength(bs);
374 if ((
size_t)cnt > nbits)
379 while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
381 BitStream_Shift32(bs);
383 cnt = lzcnt_s(~(bs->accumulator));
385 nbits = BitStream_GetRemainingLength(bs);
387 if ((
size_t)cnt > nbits)
393 BitStream_Shift(bs, (vk % 32));
395 if (BitStream_GetRemainingLength(bs) < 1)
398 BitStream_Shift(bs, 1);
402 if (BitStream_GetRemainingLength(bs) < kr)
405 bs->mask = ((1 << kr) - 1);
407 code = (UINT16)((bs->accumulator >> (32 - kr)) & bs->mask);
410 BitStream_Shift(bs, kr);
471 mag = ((INT16)((code + 1) >> 1)) * -1;
473 mag = (INT16)(code >> 1);
476 if ((pOutput - pDstData) < DstSize)
482 else if (mode == RLGR3)
489 nIdx = 32 - lzcnt_s(mag);
492 if (BitStream_GetRemainingLength(bs) < nIdx)
495 bs->mask = ((1 << nIdx) - 1);
497 val1 = ((bs->accumulator >> (32 - nIdx)) & bs->mask);
500 BitStream_Shift(bs, nIdx);
515 else if (!val1 && !val2)
528 mag = ((INT16)((val1 + 1) >> 1)) * -1;
530 mag = (INT16)(val1 >> 1);
532 if ((pOutput - pDstData) < DstSize)
539 mag = ((INT16)((val2 + 1) >> 1)) * -1;
541 mag = (INT16)(val2 >> 1);
543 if ((pOutput - pDstData) < DstSize)
552 offset = (pOutput - pDstData);
554 if (offset < rDstSize)
556 size = DstSize - offset;
557 ZeroMemory(pOutput, size * 2);
561 offset = (pOutput - pDstData);
563 if ((DstSize < 0) || (offset != (size_t)DstSize))
570 #define GetNextInput(_n) \
585 #define OutputBits(numBits, bitPattern) rfx_bitstream_put_bits(bs, bitPattern, numBits)
588 #define OutputBit(count, bit) \
591 UINT16 _b = ((bit) ? 0xFFFF : 0); \
593 for (; _c > 0; _c -= 16) \
594 rfx_bitstream_put_bits(bs, _b, (_c > 16 ? 16 : _c)); \
599 #define Get2MagSign(input) ((input) >= 0 ? 2 * (input) : -2 * (input)-1)
602 #define CodeGR(krp, val) rfx_rlgr_code_gr(bs, krp, val)
604 static void rfx_rlgr_code_gr(
RFX_BITSTREAM* bs,
int* krp, UINT32 val)
606 int kr = *krp >> LSGR;
610 UINT32 vk = (val) >> kr;
617 OutputBits(kr, val & ((1 << kr) - 1));
623 UpdateParam(*krp, -2, kr);
627 UpdateParam(*krp, vk, kr);
631 int rfx_rlgr_encode(RLGR_MODE mode,
const INT16* WINPR_RESTRICT data, UINT32 data_size,
632 BYTE* WINPR_RESTRICT buffer, UINT32 buffer_size)
638 int processed_size = 0;
643 rfx_bitstream_attach(bs, buffer, buffer_size);
651 while (data_size > 0)
666 while (input == 0 && data_size > 0)
674 while (numZeros >= runmax)
678 UpdateParam(kp, UP_GR, k);
686 OutputBits(k, numZeros);
693 (UINT32)(input < 0 ? -input : input);
694 sign = (input < 0 ? 1 : 0);
697 CodeGR(&krp, mag ? mag - 1 : 0);
699 UpdateParam(kp, -DN_GR, k);
713 twoMs = Get2MagSign(input);
721 UpdateParam(kp, -DQ_GR, k);
725 UpdateParam(kp, UQ_GR, k);
741 twoMs1 = Get2MagSign(input);
743 twoMs2 = Get2MagSign(input);
744 sum2Ms = twoMs1 + twoMs2;
746 CodeGR(&krp, sum2Ms);
749 GetMinBits(sum2Ms, nIdx);
750 OutputBits(nIdx, twoMs1);
754 if (twoMs1 && twoMs2)
756 UpdateParam(kp, -2 * DQ_GR, k);
758 else if (!twoMs1 && !twoMs2)
760 UpdateParam(kp, 2 * UQ_GR, k);
766 rfx_bitstream_flush(bs);
767 processed_size = rfx_bitstream_get_processed_bytes(bs);
768 winpr_aligned_free(bs);
770 return processed_size;