libfreerdp-codec: remove old RemoteFX RLGR implementation in favour of faster one
This commit is contained in:
parent
b7ca13f19d
commit
22d3b6c74b
@ -146,8 +146,6 @@ struct _RFX_CONTEXT
|
||||
void (*quantization_encode)(INT16* buffer, const UINT32* quantization_values);
|
||||
void (*dwt_2d_decode)(INT16* buffer, INT16* dwt_buffer);
|
||||
void (*dwt_2d_encode)(INT16* buffer, INT16* dwt_buffer);
|
||||
int (*rlgr_decode)(RLGR_MODE mode, const BYTE* data, int data_size, INT16* buffer, int buffer_size);
|
||||
int (*rlgr_encode)(RLGR_MODE mode, const INT16* data, int data_size, BYTE* buffer, int buffer_size);
|
||||
|
||||
/* private definitions */
|
||||
RFX_CONTEXT_PRIV* priv;
|
||||
@ -159,6 +157,8 @@ FREERDP_API void rfx_context_free(RFX_CONTEXT* context);
|
||||
FREERDP_API void rfx_context_set_pixel_format(RFX_CONTEXT* context, RDP_PIXEL_FORMAT pixel_format);
|
||||
FREERDP_API void rfx_context_reset(RFX_CONTEXT* context);
|
||||
|
||||
FREERDP_API int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT32 DstSize, int mode);
|
||||
|
||||
FREERDP_API RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length);
|
||||
FREERDP_API UINT16 rfx_message_get_tile_count(RFX_MESSAGE* message);
|
||||
FREERDP_API RFX_TILE* rfx_message_get_tile(RFX_MESSAGE* message, int index);
|
||||
|
@ -72,430 +72,6 @@ const char* progressive_get_block_type_string(UINT16 blockType)
|
||||
return "PROGRESSIVE_WBT_UNKNOWN";
|
||||
}
|
||||
|
||||
/* Constants used in RLGR1/RLGR3 algorithm */
|
||||
#define KPMAX (80) /* max value for kp or krp */
|
||||
#define LSGR (3) /* shift count to convert kp to k */
|
||||
#define UP_GR (4) /* increase in kp after a zero run in RL mode */
|
||||
#define DN_GR (6) /* decrease in kp after a nonzero symbol in RL mode */
|
||||
#define UQ_GR (3) /* increase in kp after nonzero symbol in GR mode */
|
||||
#define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */
|
||||
|
||||
int rfx_rlgrx_decode(BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT32 DstSize, int mode)
|
||||
{
|
||||
int vk;
|
||||
int run;
|
||||
int cnt;
|
||||
int size;
|
||||
int nbits;
|
||||
int offset;
|
||||
INT16 mag;
|
||||
int k, kp;
|
||||
int kr, krp;
|
||||
UINT16 code;
|
||||
UINT32 sign;
|
||||
UINT32 nIdx;
|
||||
UINT32 val1;
|
||||
UINT32 val2;
|
||||
INT16* pOutput;
|
||||
wBitStream* bs;
|
||||
wBitStream s_bs;
|
||||
|
||||
k = 1;
|
||||
kp = k << LSGR;
|
||||
|
||||
kr = 1;
|
||||
krp = kr << LSGR;
|
||||
|
||||
if ((mode != 1) && (mode != 3))
|
||||
mode = 1;
|
||||
|
||||
if (!pSrcData || !SrcSize)
|
||||
return -1;
|
||||
|
||||
if (!pDstData || !DstSize)
|
||||
return -1;
|
||||
|
||||
pOutput = pDstData;
|
||||
|
||||
bs = &s_bs;
|
||||
|
||||
BitStream_Attach(bs, pSrcData, SrcSize);
|
||||
BitStream_Fetch(bs);
|
||||
|
||||
while ((BitStream_GetRemainingLength(bs) > 0) && ((pOutput - pDstData) < DstSize))
|
||||
{
|
||||
if (k)
|
||||
{
|
||||
/* Run-Length (RL) Mode */
|
||||
|
||||
run = 0;
|
||||
|
||||
/* count number of leading 0s */
|
||||
|
||||
cnt = __lzcnt(bs->accumulator);
|
||||
|
||||
nbits = BitStream_GetRemainingLength(bs);
|
||||
|
||||
if (cnt > nbits)
|
||||
cnt = nbits;
|
||||
|
||||
vk = cnt;
|
||||
|
||||
while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
|
||||
{
|
||||
BitStream_Shift32(bs);
|
||||
|
||||
cnt = __lzcnt(bs->accumulator);
|
||||
|
||||
nbits = BitStream_GetRemainingLength(bs);
|
||||
|
||||
if (cnt > nbits)
|
||||
cnt = nbits;
|
||||
|
||||
vk += cnt;
|
||||
}
|
||||
|
||||
BitStream_Shift(bs, (vk % 32));
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < 1)
|
||||
break;
|
||||
|
||||
BitStream_Shift(bs, 1);
|
||||
|
||||
while (vk--)
|
||||
{
|
||||
run += (1 << k); /* add (1 << k) to run length */
|
||||
|
||||
/* update k, kp params */
|
||||
|
||||
kp += UP_GR;
|
||||
|
||||
if (kp > KPMAX)
|
||||
kp = KPMAX;
|
||||
|
||||
k = kp >> LSGR;
|
||||
}
|
||||
|
||||
/* next k bits contain run length remainder */
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < k)
|
||||
break;
|
||||
|
||||
bs->mask = ((1 << k) - 1);
|
||||
run += ((bs->accumulator >> (32 - k)) & bs->mask);
|
||||
BitStream_Shift(bs, k);
|
||||
|
||||
/* read sign bit */
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < 1)
|
||||
break;
|
||||
|
||||
sign = (bs->accumulator & 0x80000000) ? 1 : 0;
|
||||
BitStream_Shift(bs, 1);
|
||||
|
||||
/* count number of leading 1s */
|
||||
|
||||
cnt = __lzcnt(~(bs->accumulator));
|
||||
|
||||
nbits = BitStream_GetRemainingLength(bs);
|
||||
|
||||
if (cnt > nbits)
|
||||
cnt = nbits;
|
||||
|
||||
vk = cnt;
|
||||
|
||||
while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
|
||||
{
|
||||
BitStream_Shift32(bs);
|
||||
|
||||
cnt = __lzcnt(~(bs->accumulator));
|
||||
|
||||
nbits = BitStream_GetRemainingLength(bs);
|
||||
|
||||
if (cnt > nbits)
|
||||
cnt = nbits;
|
||||
|
||||
vk += cnt;
|
||||
}
|
||||
|
||||
BitStream_Shift(bs, (vk % 32));
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < 1)
|
||||
break;
|
||||
|
||||
BitStream_Shift(bs, 1);
|
||||
|
||||
/* next kr bits contain code remainder */
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < kr)
|
||||
break;
|
||||
|
||||
bs->mask = ((1 << kr) - 1);
|
||||
code = (UINT16) ((bs->accumulator >> (32 - kr)) & bs->mask);
|
||||
BitStream_Shift(bs, kr);
|
||||
|
||||
/* add (vk << kr) to code */
|
||||
|
||||
code |= (vk << kr);
|
||||
|
||||
if (!vk)
|
||||
{
|
||||
/* update kr, krp params */
|
||||
|
||||
krp -= 2;
|
||||
|
||||
if (krp < 0)
|
||||
krp = 0;
|
||||
|
||||
kr = krp >> LSGR;
|
||||
}
|
||||
else if (vk != 1)
|
||||
{
|
||||
/* update kr, krp params */
|
||||
|
||||
krp += vk;
|
||||
|
||||
if (krp > KPMAX)
|
||||
krp = KPMAX;
|
||||
|
||||
kr = krp >> LSGR;
|
||||
}
|
||||
|
||||
/* update k, kp params */
|
||||
|
||||
kp -= DN_GR;
|
||||
|
||||
if (kp < 0)
|
||||
kp = 0;
|
||||
|
||||
k = kp >> LSGR;
|
||||
|
||||
/* compute magnitude from code */
|
||||
|
||||
if (sign)
|
||||
mag = ((INT16) (code + 1)) * -1;
|
||||
else
|
||||
mag = (INT16) (code + 1);
|
||||
|
||||
/* write to output stream */
|
||||
|
||||
offset = (int) (pOutput - pDstData);
|
||||
size = run;
|
||||
|
||||
if ((offset + size) > DstSize)
|
||||
size = DstSize - offset;
|
||||
|
||||
if (size)
|
||||
{
|
||||
ZeroMemory(pOutput, size * sizeof(INT16));
|
||||
pOutput += size;
|
||||
}
|
||||
|
||||
if ((pOutput - pDstData) < DstSize)
|
||||
{
|
||||
*pOutput = mag;
|
||||
pOutput++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Golomb-Rice (GR) Mode */
|
||||
|
||||
/* count number of leading 1s */
|
||||
|
||||
cnt = __lzcnt(~(bs->accumulator));
|
||||
|
||||
nbits = BitStream_GetRemainingLength(bs);
|
||||
|
||||
if (cnt > nbits)
|
||||
cnt = nbits;
|
||||
|
||||
vk = cnt;
|
||||
|
||||
while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
|
||||
{
|
||||
BitStream_Shift32(bs);
|
||||
|
||||
cnt = __lzcnt(~(bs->accumulator));
|
||||
|
||||
nbits = BitStream_GetRemainingLength(bs);
|
||||
|
||||
if (cnt > nbits)
|
||||
cnt = nbits;
|
||||
|
||||
vk += cnt;
|
||||
}
|
||||
|
||||
BitStream_Shift(bs, (vk % 32));
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < 1)
|
||||
break;
|
||||
|
||||
BitStream_Shift(bs, 1);
|
||||
|
||||
/* next kr bits contain code remainder */
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < kr)
|
||||
break;
|
||||
|
||||
bs->mask = ((1 << kr) - 1);
|
||||
code = (UINT16) ((bs->accumulator >> (32 - kr)) & bs->mask);
|
||||
BitStream_Shift(bs, kr);
|
||||
|
||||
/* add (vk << kr) to code */
|
||||
|
||||
code |= (vk << kr);
|
||||
|
||||
if (!vk)
|
||||
{
|
||||
/* update kr, krp params */
|
||||
|
||||
krp -= 2;
|
||||
|
||||
if (krp < 0)
|
||||
krp = 0;
|
||||
|
||||
kr = krp >> LSGR;
|
||||
}
|
||||
else if (vk != 1)
|
||||
{
|
||||
/* update kr, krp params */
|
||||
|
||||
krp += vk;
|
||||
|
||||
if (krp > KPMAX)
|
||||
krp = KPMAX;
|
||||
|
||||
kr = krp >> LSGR;
|
||||
}
|
||||
|
||||
if (mode == 1) /* RLGR1 */
|
||||
{
|
||||
if (!code)
|
||||
{
|
||||
/* update k, kp params */
|
||||
|
||||
kp += UQ_GR;
|
||||
|
||||
if (kp > KPMAX)
|
||||
kp = KPMAX;
|
||||
|
||||
k = kp >> LSGR;
|
||||
|
||||
mag = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* update k, kp params */
|
||||
|
||||
kp -= DQ_GR;
|
||||
|
||||
if (kp < 0)
|
||||
kp = 0;
|
||||
|
||||
k = kp >> LSGR;
|
||||
|
||||
/*
|
||||
* code = 2 * mag - sign
|
||||
* sign + code = 2 * mag
|
||||
*/
|
||||
|
||||
if (code & 1)
|
||||
mag = ((INT16) ((code + 1) >> 1)) * -1;
|
||||
else
|
||||
mag = (INT16) (code >> 1);
|
||||
}
|
||||
|
||||
if ((pOutput - pDstData) < DstSize)
|
||||
{
|
||||
*pOutput = mag;
|
||||
pOutput++;
|
||||
}
|
||||
}
|
||||
else if (mode == 3) /* RLGR3 */
|
||||
{
|
||||
nIdx = 0;
|
||||
|
||||
if (code)
|
||||
{
|
||||
mag = (UINT32) code;
|
||||
nIdx = 32 - __lzcnt(mag);
|
||||
}
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < nIdx)
|
||||
break;
|
||||
|
||||
bs->mask = ((1 << nIdx) - 1);
|
||||
val1 = ((bs->accumulator >> (32 - nIdx)) & bs->mask);
|
||||
BitStream_Shift(bs, nIdx);
|
||||
|
||||
val2 = code - val1;
|
||||
|
||||
if (val1 && val2)
|
||||
{
|
||||
/* update k, kp params */
|
||||
|
||||
kp -= (2 * DQ_GR);
|
||||
|
||||
if (kp < 0)
|
||||
kp = 0;
|
||||
|
||||
k = kp >> LSGR;
|
||||
}
|
||||
else if (!val1 && !val2)
|
||||
{
|
||||
/* update k, kp params */
|
||||
|
||||
kp += (2 * UQ_GR);
|
||||
|
||||
if (kp > KPMAX)
|
||||
kp = KPMAX;
|
||||
|
||||
k = kp >> LSGR;
|
||||
}
|
||||
|
||||
if (val1 & 1)
|
||||
mag = ((INT16) ((val1 + 1) >> 1)) * -1;
|
||||
else
|
||||
mag = (INT16) (val1 >> 1);
|
||||
|
||||
if ((pOutput - pDstData) < DstSize)
|
||||
{
|
||||
*pOutput = mag;
|
||||
pOutput++;
|
||||
}
|
||||
|
||||
if (val2 & 1)
|
||||
mag = ((INT16) ((val2 + 1) >> 1)) * -1;
|
||||
else
|
||||
mag = (INT16) (val2 >> 1);
|
||||
|
||||
if ((pOutput - pDstData) < DstSize)
|
||||
{
|
||||
*pOutput = mag;
|
||||
pOutput++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offset = (int) (pOutput - pDstData);
|
||||
|
||||
if (offset < DstSize)
|
||||
{
|
||||
size = DstSize - offset;
|
||||
ZeroMemory(pOutput, size * 2);
|
||||
pOutput += size;
|
||||
}
|
||||
|
||||
offset = (int) (pOutput - pDstData);
|
||||
|
||||
if (offset != DstSize)
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int progressive_decompress_tile_first(PROGRESSIVE_CONTEXT* progressive, RFX_PROGRESSIVE_TILE* tile)
|
||||
{
|
||||
PROGRESSIVE_BLOCK_REGION* region;
|
||||
|
@ -330,8 +330,6 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder)
|
||||
context->quantization_encode = rfx_quantization_encode;
|
||||
context->dwt_2d_decode = rfx_dwt_2d_decode;
|
||||
context->dwt_2d_encode = rfx_dwt_2d_encode;
|
||||
context->rlgr_decode = rfx_rlgr_decode;
|
||||
context->rlgr_encode = rfx_rlgr_encode;
|
||||
|
||||
RFX_INIT_SIMD(context);
|
||||
|
||||
|
@ -103,7 +103,7 @@ static void rfx_decode_component(RFX_CONTEXT* context, const UINT32* quantizatio
|
||||
PROFILER_ENTER(context->priv->prof_rfx_decode_component);
|
||||
|
||||
PROFILER_ENTER(context->priv->prof_rfx_rlgr_decode);
|
||||
context->rlgr_decode(context->mode, data, size, buffer, 4096);
|
||||
rfx_rlgr_decode(data, size, buffer, 4096, (context->mode == RLGR1) ? 1 : 3);
|
||||
PROFILER_EXIT(context->priv->prof_rfx_rlgr_decode);
|
||||
|
||||
PROFILER_ENTER(context->priv->prof_rfx_differential_decode);
|
||||
|
@ -209,7 +209,7 @@ static void rfx_encode_component(RFX_CONTEXT* context, const UINT32* quantizatio
|
||||
PROFILER_EXIT(context->priv->prof_rfx_differential_encode);
|
||||
|
||||
PROFILER_ENTER(context->priv->prof_rfx_rlgr_encode);
|
||||
*size = context->rlgr_encode(context->mode, data, 4096, buffer, buffer_size);
|
||||
*size = rfx_rlgr_encode(context->mode, data, 4096, buffer, buffer_size);
|
||||
PROFILER_EXIT(context->priv->prof_rfx_rlgr_encode);
|
||||
|
||||
PROFILER_EXIT(context->priv->prof_rfx_encode_component);
|
||||
|
@ -31,43 +31,20 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/bitstream.h>
|
||||
|
||||
#include "rfx_bitstream.h"
|
||||
|
||||
#include "rfx_rlgr.h"
|
||||
|
||||
/* Constants used within the RLGR1/RLGR3 algorithm */
|
||||
#define KPMAX (80) /* max value for kp or krp */
|
||||
#define LSGR (3) /* shift count to convert kp to k */
|
||||
#define UP_GR (4) /* increase in kp after a zero run in RL mode */
|
||||
#define DN_GR (6) /* decrease in kp after a nonzero symbol in RL mode */
|
||||
#define UQ_GR (3) /* increase in kp after nonzero symbol in GR mode */
|
||||
#define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */
|
||||
|
||||
/* Gets (returns) the next nBits from the bitstream */
|
||||
#define GetBits(nBits, r) rfx_bitstream_get_bits(bs, nBits, r)
|
||||
|
||||
/* From current output pointer, write "value", check and update buffer_size */
|
||||
#define WriteValue(value) \
|
||||
{ \
|
||||
if (buffer_size > 0) \
|
||||
*dst++ = (value); \
|
||||
buffer_size--; \
|
||||
}
|
||||
|
||||
/* From current output pointer, write next nZeroes terms with value 0, check and update buffer_size */
|
||||
#define WriteZeroes(nZeroes) \
|
||||
{ \
|
||||
int nZeroesWritten = (nZeroes); \
|
||||
if (nZeroesWritten > buffer_size) \
|
||||
nZeroesWritten = buffer_size; \
|
||||
if (nZeroesWritten > 0) \
|
||||
{ \
|
||||
memset(dst, 0, nZeroesWritten * sizeof(INT16)); \
|
||||
dst += nZeroesWritten; \
|
||||
} \
|
||||
buffer_size -= (nZeroes); \
|
||||
}
|
||||
/* Constants used in RLGR1/RLGR3 algorithm */
|
||||
#define KPMAX (80) /* max value for kp or krp */
|
||||
#define LSGR (3) /* shift count to convert kp to k */
|
||||
#define UP_GR (4) /* increase in kp after a zero run in RL mode */
|
||||
#define DN_GR (6) /* decrease in kp after a nonzero symbol in RL mode */
|
||||
#define UQ_GR (3) /* increase in kp after nonzero symbol in GR mode */
|
||||
#define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */
|
||||
|
||||
/* Returns the least number of bits required to represent a given value */
|
||||
#define GetMinBits(_val, _nbits) \
|
||||
@ -81,9 +58,6 @@
|
||||
} \
|
||||
}
|
||||
|
||||
/* Converts from (2 * magnitude - sign) to integer */
|
||||
#define GetIntFrom2MagSign(twoMs) (((twoMs) & 1) ? -1 * (INT16)(((twoMs) + 1) >> 1) : (INT16)((twoMs) >> 1))
|
||||
|
||||
/*
|
||||
* Update the passed parameter and clamp it to the range [0, KPMAX]
|
||||
* Return the value of parameter right-shifted by LSGR
|
||||
@ -98,147 +72,420 @@
|
||||
_k = (_param >> LSGR); \
|
||||
}
|
||||
|
||||
/* Outputs the Golomb/Rice encoding of a non-negative integer */
|
||||
#define GetGRCode(krp, kr, vk, _mag) \
|
||||
vk = 0; \
|
||||
_mag = 0; \
|
||||
/* chew up/count leading 1s and escape 0 */ \
|
||||
do { \
|
||||
GetBits(1, r); \
|
||||
if (r == 1) \
|
||||
vk++; \
|
||||
else \
|
||||
break; \
|
||||
} while (1); \
|
||||
/* get next *kr bits, and combine with leading 1s */ \
|
||||
GetBits(*kr, _mag); \
|
||||
_mag |= (vk << *kr); \
|
||||
/* adjust krp and kr based on vk */ \
|
||||
if (!vk) { \
|
||||
UpdateParam(*krp, -2, *kr); \
|
||||
} \
|
||||
else if (vk != 1) { \
|
||||
UpdateParam(*krp, vk, *kr); /* at 1, no change! */ \
|
||||
}
|
||||
|
||||
int rfx_rlgr_decode(RLGR_MODE mode, const BYTE* data, int data_size, INT16* buffer, int buffer_size)
|
||||
int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT32 DstSize, int mode)
|
||||
{
|
||||
int k;
|
||||
int kp;
|
||||
int kr;
|
||||
int krp;
|
||||
UINT16 r;
|
||||
INT16* dst;
|
||||
RFX_BITSTREAM* bs;
|
||||
|
||||
int vk;
|
||||
UINT16 mag16;
|
||||
int run;
|
||||
int cnt;
|
||||
int size;
|
||||
int nbits;
|
||||
int offset;
|
||||
INT16 mag;
|
||||
int k, kp;
|
||||
int kr, krp;
|
||||
UINT16 code;
|
||||
UINT32 sign;
|
||||
UINT32 nIdx;
|
||||
UINT32 val1;
|
||||
UINT32 val2;
|
||||
INT16* pOutput;
|
||||
wBitStream* bs;
|
||||
wBitStream s_bs;
|
||||
|
||||
bs = (RFX_BITSTREAM*) malloc(sizeof(RFX_BITSTREAM));
|
||||
ZeroMemory(bs, sizeof(RFX_BITSTREAM));
|
||||
|
||||
rfx_bitstream_attach(bs, data, data_size);
|
||||
dst = buffer;
|
||||
|
||||
/* initialize the parameters */
|
||||
k = 1;
|
||||
kp = k << LSGR;
|
||||
|
||||
kr = 1;
|
||||
krp = kr << LSGR;
|
||||
|
||||
while (!rfx_bitstream_eos(bs) && buffer_size > 0)
|
||||
if ((mode != 1) && (mode != 3))
|
||||
mode = 1;
|
||||
|
||||
if (!pSrcData || !SrcSize)
|
||||
return -1;
|
||||
|
||||
if (!pDstData || !DstSize)
|
||||
return -1;
|
||||
|
||||
pOutput = pDstData;
|
||||
|
||||
bs = &s_bs;
|
||||
|
||||
BitStream_Attach(bs, pSrcData, SrcSize);
|
||||
BitStream_Fetch(bs);
|
||||
|
||||
while ((BitStream_GetRemainingLength(bs) > 0) && ((pOutput - pDstData) < DstSize))
|
||||
{
|
||||
int run;
|
||||
if (k)
|
||||
{
|
||||
int mag;
|
||||
UINT32 sign;
|
||||
/* Run-Length (RL) Mode */
|
||||
|
||||
/* RL MODE */
|
||||
while (!rfx_bitstream_eos(bs))
|
||||
run = 0;
|
||||
|
||||
/* count number of leading 0s */
|
||||
|
||||
cnt = __lzcnt(bs->accumulator);
|
||||
|
||||
nbits = BitStream_GetRemainingLength(bs);
|
||||
|
||||
if (cnt > nbits)
|
||||
cnt = nbits;
|
||||
|
||||
vk = cnt;
|
||||
|
||||
while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
|
||||
{
|
||||
GetBits(1, r);
|
||||
if (r)
|
||||
break;
|
||||
/* we have an RL escape "0", which translates to a run (1<<k) of zeros */
|
||||
WriteZeroes(1 << k);
|
||||
UpdateParam(kp, UP_GR, k); /* raise k and kp up because of zero run */
|
||||
BitStream_Shift32(bs);
|
||||
|
||||
cnt = __lzcnt(bs->accumulator);
|
||||
|
||||
nbits = BitStream_GetRemainingLength(bs);
|
||||
|
||||
if (cnt > nbits)
|
||||
cnt = nbits;
|
||||
|
||||
vk += cnt;
|
||||
}
|
||||
|
||||
/* next k bits will contain remaining run or zeros */
|
||||
GetBits(k, run);
|
||||
WriteZeroes(run);
|
||||
BitStream_Shift(bs, (vk % 32));
|
||||
|
||||
/* get nonzero value, starting with sign bit and then GRCode for magnitude -1 */
|
||||
GetBits(1, sign);
|
||||
if (BitStream_GetRemainingLength(bs) < 1)
|
||||
break;
|
||||
|
||||
/* magnitude - 1 was coded (because it was nonzero) */
|
||||
GetGRCode(&krp, &kr, vk, mag16)
|
||||
mag = (int) (mag16 + 1);
|
||||
BitStream_Shift(bs, 1);
|
||||
|
||||
WriteValue(sign ? -mag : mag);
|
||||
UpdateParam(kp, -DN_GR, k); /* lower k and kp because of nonzero term */
|
||||
while (vk--)
|
||||
{
|
||||
run += (1 << k); /* add (1 << k) to run length */
|
||||
|
||||
/* update k, kp params */
|
||||
|
||||
kp += UP_GR;
|
||||
|
||||
if (kp > KPMAX)
|
||||
kp = KPMAX;
|
||||
|
||||
k = kp >> LSGR;
|
||||
}
|
||||
|
||||
/* next k bits contain run length remainder */
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < k)
|
||||
break;
|
||||
|
||||
bs->mask = ((1 << k) - 1);
|
||||
run += ((bs->accumulator >> (32 - k)) & bs->mask);
|
||||
BitStream_Shift(bs, k);
|
||||
|
||||
/* read sign bit */
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < 1)
|
||||
break;
|
||||
|
||||
sign = (bs->accumulator & 0x80000000) ? 1 : 0;
|
||||
BitStream_Shift(bs, 1);
|
||||
|
||||
/* count number of leading 1s */
|
||||
|
||||
cnt = __lzcnt(~(bs->accumulator));
|
||||
|
||||
nbits = BitStream_GetRemainingLength(bs);
|
||||
|
||||
if (cnt > nbits)
|
||||
cnt = nbits;
|
||||
|
||||
vk = cnt;
|
||||
|
||||
while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
|
||||
{
|
||||
BitStream_Shift32(bs);
|
||||
|
||||
cnt = __lzcnt(~(bs->accumulator));
|
||||
|
||||
nbits = BitStream_GetRemainingLength(bs);
|
||||
|
||||
if (cnt > nbits)
|
||||
cnt = nbits;
|
||||
|
||||
vk += cnt;
|
||||
}
|
||||
|
||||
BitStream_Shift(bs, (vk % 32));
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < 1)
|
||||
break;
|
||||
|
||||
BitStream_Shift(bs, 1);
|
||||
|
||||
/* next kr bits contain code remainder */
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < kr)
|
||||
break;
|
||||
|
||||
bs->mask = ((1 << kr) - 1);
|
||||
code = (UINT16) ((bs->accumulator >> (32 - kr)) & bs->mask);
|
||||
BitStream_Shift(bs, kr);
|
||||
|
||||
/* add (vk << kr) to code */
|
||||
|
||||
code |= (vk << kr);
|
||||
|
||||
if (!vk)
|
||||
{
|
||||
/* update kr, krp params */
|
||||
|
||||
krp -= 2;
|
||||
|
||||
if (krp < 0)
|
||||
krp = 0;
|
||||
|
||||
kr = krp >> LSGR;
|
||||
}
|
||||
else if (vk != 1)
|
||||
{
|
||||
/* update kr, krp params */
|
||||
|
||||
krp += vk;
|
||||
|
||||
if (krp > KPMAX)
|
||||
krp = KPMAX;
|
||||
|
||||
kr = krp >> LSGR;
|
||||
}
|
||||
|
||||
/* update k, kp params */
|
||||
|
||||
kp -= DN_GR;
|
||||
|
||||
if (kp < 0)
|
||||
kp = 0;
|
||||
|
||||
k = kp >> LSGR;
|
||||
|
||||
/* compute magnitude from code */
|
||||
|
||||
if (sign)
|
||||
mag = ((INT16) (code + 1)) * -1;
|
||||
else
|
||||
mag = (INT16) (code + 1);
|
||||
|
||||
/* write to output stream */
|
||||
|
||||
offset = (int) (pOutput - pDstData);
|
||||
size = run;
|
||||
|
||||
if ((offset + size) > DstSize)
|
||||
size = DstSize - offset;
|
||||
|
||||
if (size)
|
||||
{
|
||||
ZeroMemory(pOutput, size * sizeof(INT16));
|
||||
pOutput += size;
|
||||
}
|
||||
|
||||
if ((pOutput - pDstData) < DstSize)
|
||||
{
|
||||
*pOutput = mag;
|
||||
pOutput++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 mag;
|
||||
UINT32 nIdx;
|
||||
UINT32 val1;
|
||||
UINT32 val2;
|
||||
/* Golomb-Rice (GR) Mode */
|
||||
|
||||
/* GR (GOLOMB-RICE) MODE */
|
||||
GetGRCode(&krp, &kr, vk, mag16) /* values coded are 2 * magnitude - sign */
|
||||
mag = (UINT32) mag16;
|
||||
/* count number of leading 1s */
|
||||
|
||||
if (mode == RLGR1)
|
||||
cnt = __lzcnt(~(bs->accumulator));
|
||||
|
||||
nbits = BitStream_GetRemainingLength(bs);
|
||||
|
||||
if (cnt > nbits)
|
||||
cnt = nbits;
|
||||
|
||||
vk = cnt;
|
||||
|
||||
while ((cnt == 32) && (BitStream_GetRemainingLength(bs) > 0))
|
||||
{
|
||||
if (!mag)
|
||||
BitStream_Shift32(bs);
|
||||
|
||||
cnt = __lzcnt(~(bs->accumulator));
|
||||
|
||||
nbits = BitStream_GetRemainingLength(bs);
|
||||
|
||||
if (cnt > nbits)
|
||||
cnt = nbits;
|
||||
|
||||
vk += cnt;
|
||||
}
|
||||
|
||||
BitStream_Shift(bs, (vk % 32));
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < 1)
|
||||
break;
|
||||
|
||||
BitStream_Shift(bs, 1);
|
||||
|
||||
/* next kr bits contain code remainder */
|
||||
|
||||
if (BitStream_GetRemainingLength(bs) < kr)
|
||||
break;
|
||||
|
||||
bs->mask = ((1 << kr) - 1);
|
||||
code = (UINT16) ((bs->accumulator >> (32 - kr)) & bs->mask);
|
||||
BitStream_Shift(bs, kr);
|
||||
|
||||
/* add (vk << kr) to code */
|
||||
|
||||
code |= (vk << kr);
|
||||
|
||||
if (!vk)
|
||||
{
|
||||
/* update kr, krp params */
|
||||
|
||||
krp -= 2;
|
||||
|
||||
if (krp < 0)
|
||||
krp = 0;
|
||||
|
||||
kr = krp >> LSGR;
|
||||
}
|
||||
else if (vk != 1)
|
||||
{
|
||||
/* update kr, krp params */
|
||||
|
||||
krp += vk;
|
||||
|
||||
if (krp > KPMAX)
|
||||
krp = KPMAX;
|
||||
|
||||
kr = krp >> LSGR;
|
||||
}
|
||||
|
||||
if (mode == 1) /* RLGR1 */
|
||||
{
|
||||
if (!code)
|
||||
{
|
||||
WriteValue(0);
|
||||
UpdateParam(kp, UQ_GR, k); /* raise k and kp due to zero */
|
||||
/* update k, kp params */
|
||||
|
||||
kp += UQ_GR;
|
||||
|
||||
if (kp > KPMAX)
|
||||
kp = KPMAX;
|
||||
|
||||
k = kp >> LSGR;
|
||||
|
||||
mag = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteValue(GetIntFrom2MagSign(mag));
|
||||
UpdateParam(kp, -DQ_GR, k); /* lower k and kp due to nonzero */
|
||||
/* update k, kp params */
|
||||
|
||||
kp -= DQ_GR;
|
||||
|
||||
if (kp < 0)
|
||||
kp = 0;
|
||||
|
||||
k = kp >> LSGR;
|
||||
|
||||
/*
|
||||
* code = 2 * mag - sign
|
||||
* sign + code = 2 * mag
|
||||
*/
|
||||
|
||||
if (code & 1)
|
||||
mag = ((INT16) ((code + 1) >> 1)) * -1;
|
||||
else
|
||||
mag = (INT16) (code >> 1);
|
||||
}
|
||||
|
||||
if ((pOutput - pDstData) < DstSize)
|
||||
{
|
||||
*pOutput = mag;
|
||||
pOutput++;
|
||||
}
|
||||
}
|
||||
else /* mode == RLGR3 */
|
||||
else if (mode == 3) /* RLGR3 */
|
||||
{
|
||||
/*
|
||||
* In GR mode FOR RLGR3, we have encoded the
|
||||
* sum of two (2 * mag - sign) values
|
||||
*/
|
||||
nIdx = 0;
|
||||
|
||||
/* maximum possible bits for first term */
|
||||
GetMinBits(mag, nIdx);
|
||||
if (code)
|
||||
{
|
||||
mag = (UINT32) code;
|
||||
nIdx = 32 - __lzcnt(mag);
|
||||
}
|
||||
|
||||
/* decode val1 is first term's (2 * mag - sign) value */
|
||||
GetBits(nIdx, val1);
|
||||
if (BitStream_GetRemainingLength(bs) < nIdx)
|
||||
break;
|
||||
|
||||
/* val2 is second term's (2 * mag - sign) value */
|
||||
val2 = mag - val1;
|
||||
bs->mask = ((1 << nIdx) - 1);
|
||||
val1 = ((bs->accumulator >> (32 - nIdx)) & bs->mask);
|
||||
BitStream_Shift(bs, nIdx);
|
||||
|
||||
val2 = code - val1;
|
||||
|
||||
if (val1 && val2)
|
||||
{
|
||||
/* raise k and kp if both terms nonzero */
|
||||
UpdateParam(kp, -2 * DQ_GR, k);
|
||||
/* update k, kp params */
|
||||
|
||||
kp -= (2 * DQ_GR);
|
||||
|
||||
if (kp < 0)
|
||||
kp = 0;
|
||||
|
||||
k = kp >> LSGR;
|
||||
}
|
||||
else if (!val1 && !val2)
|
||||
{
|
||||
/* lower k and kp if both terms zero */
|
||||
UpdateParam(kp, 2 * UQ_GR, k);
|
||||
/* update k, kp params */
|
||||
|
||||
kp += (2 * UQ_GR);
|
||||
|
||||
if (kp > KPMAX)
|
||||
kp = KPMAX;
|
||||
|
||||
k = kp >> LSGR;
|
||||
}
|
||||
|
||||
WriteValue(GetIntFrom2MagSign(val1));
|
||||
WriteValue(GetIntFrom2MagSign(val2));
|
||||
if (val1 & 1)
|
||||
mag = ((INT16) ((val1 + 1) >> 1)) * -1;
|
||||
else
|
||||
mag = (INT16) (val1 >> 1);
|
||||
|
||||
if ((pOutput - pDstData) < DstSize)
|
||||
{
|
||||
*pOutput = mag;
|
||||
pOutput++;
|
||||
}
|
||||
|
||||
if (val2 & 1)
|
||||
mag = ((INT16) ((val2 + 1) >> 1)) * -1;
|
||||
else
|
||||
mag = (INT16) (val2 >> 1);
|
||||
|
||||
if ((pOutput - pDstData) < DstSize)
|
||||
{
|
||||
*pOutput = mag;
|
||||
pOutput++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(bs);
|
||||
offset = (int) (pOutput - pDstData);
|
||||
|
||||
return (dst - buffer);
|
||||
if (offset < DstSize)
|
||||
{
|
||||
size = DstSize - offset;
|
||||
ZeroMemory(pOutput, size * 2);
|
||||
pOutput += size;
|
||||
}
|
||||
|
||||
offset = (int) (pOutput - pDstData);
|
||||
|
||||
if (offset != DstSize)
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns the next coefficient (a signed int) to encode, from the input stream */
|
||||
|
@ -22,7 +22,6 @@
|
||||
|
||||
#include <freerdp/codec/rfx.h>
|
||||
|
||||
int rfx_rlgr_decode(RLGR_MODE mode, const BYTE* data, int data_size, INT16* buffer, int buffer_size);
|
||||
int rfx_rlgr_encode(RLGR_MODE mode, const INT16* data, int data_size, BYTE* buffer, int buffer_size);
|
||||
|
||||
#endif /* __RFX_RLGR_H */
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
struct _wBitStream
|
||||
{
|
||||
BYTE* buffer;
|
||||
const BYTE* buffer;
|
||||
BYTE* pointer;
|
||||
int position;
|
||||
int length;
|
||||
@ -140,7 +140,7 @@ extern "C" {
|
||||
WINPR_API void BitDump(const BYTE* buffer, UINT32 length, UINT32 flags);
|
||||
WINPR_API UINT32 ReverseBits32(UINT32 bits, UINT32 nbits);
|
||||
|
||||
WINPR_API void BitStream_Attach(wBitStream* bs, BYTE* buffer, UINT32 capacity);
|
||||
WINPR_API void BitStream_Attach(wBitStream* bs, const BYTE* buffer, UINT32 capacity);
|
||||
|
||||
WINPR_API wBitStream* BitStream_New();
|
||||
WINPR_API void BitStream_Free(wBitStream* bs);
|
||||
|
@ -316,13 +316,13 @@ void BitStream_Write_Bits(wBitStream* bs, UINT32 bits, UINT32 nbits)
|
||||
|
||||
#endif
|
||||
|
||||
void BitStream_Attach(wBitStream* bs, BYTE* buffer, UINT32 capacity)
|
||||
void BitStream_Attach(wBitStream* bs, const BYTE* buffer, UINT32 capacity)
|
||||
{
|
||||
bs->position = 0;
|
||||
bs->buffer = buffer;
|
||||
bs->offset = 0;
|
||||
bs->accumulator = 0;
|
||||
bs->pointer = bs->buffer;
|
||||
bs->pointer = (BYTE*) bs->buffer;
|
||||
bs->capacity = capacity;
|
||||
bs->length = bs->capacity * 8;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user