mirror of https://github.com/FreeRDP/FreeRDP
libfreerdp-codec: start MPPC compressor
This commit is contained in:
parent
77e91aa762
commit
d9a2fb4ff9
|
@ -45,6 +45,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FREERDP_API UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32* pSize);
|
FREERDP_API UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32* pSize);
|
||||||
|
FREERDP_API UINT32 mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32* pSize, UINT32 flags);
|
||||||
|
|
||||||
FREERDP_API MPPC_CONTEXT* mppc_context_new(DWORD CompressionLevel, BOOL Compressor);
|
FREERDP_API MPPC_CONTEXT* mppc_context_new(DWORD CompressionLevel, BOOL Compressor);
|
||||||
FREERDP_API void mppc_context_free(MPPC_CONTEXT* mppc);
|
FREERDP_API void mppc_context_free(MPPC_CONTEXT* mppc);
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
#include <winpr/print.h>
|
#include <winpr/print.h>
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
#include <winpr/collections.h>
|
#include <winpr/bitstream.h>
|
||||||
|
|
||||||
#include <freerdp/codec/mppc_enc.h>
|
#include <freerdp/codec/mppc_enc.h>
|
||||||
#include <freerdp/codec/mppc_dec.h>
|
#include <freerdp/codec/mppc_dec.h>
|
||||||
|
@ -72,6 +72,179 @@ const UINT32 MPPC_MATCH_TABLE[256] =
|
||||||
|
|
||||||
//#define DEBUG_MPPC 1
|
//#define DEBUG_MPPC 1
|
||||||
|
|
||||||
|
void BitStream_Prefetch(wBitStream* bs)
|
||||||
|
{
|
||||||
|
(bs->prefetch) = 0;
|
||||||
|
if ((bs->pointer - bs->buffer) < (bs->capacity + 4))
|
||||||
|
(bs->prefetch) |= (*(bs->pointer + 4) << 24);
|
||||||
|
if ((bs->pointer - bs->buffer) < (bs->capacity + 5))
|
||||||
|
(bs->prefetch) |= (*(bs->pointer + 5) << 16);
|
||||||
|
if ((bs->pointer - bs->buffer) < (bs->capacity + 6))
|
||||||
|
(bs->prefetch) |= (*(bs->pointer + 6) << 8);
|
||||||
|
if ((bs->pointer - bs->buffer) < (bs->capacity + 7))
|
||||||
|
(bs->prefetch) |= (*(bs->pointer + 7) << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitStream_Fetch(wBitStream* bs)
|
||||||
|
{
|
||||||
|
(bs->accumulator) = 0;
|
||||||
|
if ((bs->pointer - bs->buffer) < (bs->capacity + 0))
|
||||||
|
(bs->accumulator) |= (*(bs->pointer + 0) << 24);
|
||||||
|
if ((bs->pointer - bs->buffer) < (bs->capacity + 1))
|
||||||
|
(bs->accumulator) |= (*(bs->pointer + 1) << 16);
|
||||||
|
if ((bs->pointer - bs->buffer) < (bs->capacity + 2))
|
||||||
|
(bs->accumulator) |= (*(bs->pointer + 2) << 8);
|
||||||
|
if ((bs->pointer - bs->buffer) < (bs->capacity + 3))
|
||||||
|
(bs->accumulator) |= (*(bs->pointer + 3) << 0);
|
||||||
|
|
||||||
|
BitStream_Prefetch(bs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitStream_Shift(wBitStream* bs, UINT32 nbits)
|
||||||
|
{
|
||||||
|
printf("BitStream_Shift: nbits: %d position: %d offset: %d Accumulator: 0x%04X\n",
|
||||||
|
nbits, bs->position, bs->offset, bs->accumulator);
|
||||||
|
|
||||||
|
bs->accumulator <<= nbits;
|
||||||
|
bs->position += nbits;
|
||||||
|
bs->offset += nbits;
|
||||||
|
|
||||||
|
printf("BitStream_Shift Accumulator shifted: 0x%04X\n", bs->accumulator);
|
||||||
|
|
||||||
|
bs->mask = ((1 << nbits) - 1);
|
||||||
|
bs->accumulator |= ((bs->prefetch >> (32 - nbits)) & bs->mask);
|
||||||
|
bs->prefetch <<= nbits;
|
||||||
|
|
||||||
|
if (bs->offset >= 32)
|
||||||
|
{
|
||||||
|
bs->offset = bs->offset - 32;
|
||||||
|
bs->pointer += 4;
|
||||||
|
|
||||||
|
if (bs->offset)
|
||||||
|
printf("%d bits missing\n", bs->offset);
|
||||||
|
|
||||||
|
BitStream_Prefetch(bs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32* pSize, UINT32 flags)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
BYTE Literal;
|
||||||
|
UINT32 CopyOffset;
|
||||||
|
UINT32 accumulator;
|
||||||
|
wBitStream* bs = mppc->bs;
|
||||||
|
|
||||||
|
BitStream_Attach(bs, pSrcData, *pSize);
|
||||||
|
|
||||||
|
if (flags & PACKET_AT_FRONT)
|
||||||
|
{
|
||||||
|
mppc->HistoryPtr = 0;
|
||||||
|
mppc->pHistoryPtr = &(mppc->HistoryBuffer[mppc->HistoryPtr]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & PACKET_FLUSHED)
|
||||||
|
{
|
||||||
|
mppc->HistoryPtr = 0;
|
||||||
|
mppc->pHistoryPtr = &(mppc->HistoryBuffer[mppc->HistoryPtr]);
|
||||||
|
|
||||||
|
ZeroMemory(mppc->HistoryBuffer, mppc->HistoryBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(flags & PACKET_COMPRESSED))
|
||||||
|
{
|
||||||
|
CopyMemory(mppc->pHistoryPtr, pSrcData, *pSize);
|
||||||
|
mppc->HistoryPtr += *pSize;
|
||||||
|
mppc->pHistoryPtr += *pSize;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BitStream_Fetch(bs);
|
||||||
|
|
||||||
|
for (index = 0; index < *pSize; index++)
|
||||||
|
{
|
||||||
|
accumulator = bs->accumulator;
|
||||||
|
|
||||||
|
if ((accumulator & 0x80000000) == 0x00000000)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Literal, less than 0x80
|
||||||
|
* bit 0 followed by the lower 7 bits of the literal
|
||||||
|
*/
|
||||||
|
|
||||||
|
Literal = ((accumulator & 0x7F000000) >> 24);
|
||||||
|
printf("%c\n", Literal);
|
||||||
|
|
||||||
|
BitStream_Shift(bs, 8);
|
||||||
|
}
|
||||||
|
else if ((accumulator & 0xC0000000) == 0x80000000)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Literal, greater than 0x7F
|
||||||
|
* bits 10 followed by the lower 7 bits of the literal
|
||||||
|
*/
|
||||||
|
|
||||||
|
Literal = ((accumulator & 0x3F800000) >> 23) + 0x80;
|
||||||
|
printf("%c\n", Literal);
|
||||||
|
|
||||||
|
BitStream_Shift(bs, 9);
|
||||||
|
}
|
||||||
|
else if ((accumulator & 0xF8000000) == 0xF8000000)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* CopyOffset, range [0, 63]
|
||||||
|
* bits 11111 + lower 6 bits of CopyOffset
|
||||||
|
*/
|
||||||
|
|
||||||
|
CopyOffset = ((accumulator >> 21) & 0x3F);
|
||||||
|
printf("CopyOffset: %d\n", (int) CopyOffset);
|
||||||
|
BitStream_Shift(bs, 11);
|
||||||
|
}
|
||||||
|
else if ((accumulator & 0xF8000000) == 0xF0000000)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* CopyOffset, range [64, 319]
|
||||||
|
* bits 11110 + lower 8 bits of (CopyOffset - 64)
|
||||||
|
*/
|
||||||
|
|
||||||
|
CopyOffset = ((accumulator >> 19) & 0xFF) + 64;
|
||||||
|
printf("CopyOffset: %d\n", (int) CopyOffset);
|
||||||
|
|
||||||
|
BitStream_Shift(bs, 13);
|
||||||
|
}
|
||||||
|
else if ((accumulator & 0xF0000000) == 0xE0000000)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* CopyOffset, range [320, 2367]
|
||||||
|
* bits 1110 + lower 11 bits of (CopyOffset - 320)
|
||||||
|
*/
|
||||||
|
|
||||||
|
CopyOffset = ((accumulator >> 17) & 0x7FF) + 320;
|
||||||
|
printf("CopyOffset: %d\n", (int) CopyOffset);
|
||||||
|
|
||||||
|
BitStream_Shift(bs, 15);
|
||||||
|
}
|
||||||
|
else if ((accumulator & 0xE0000000) == 0xC0000000)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* CopyOffset, range [2368, ]
|
||||||
|
* bits 110 + lower 16 bits of (CopyOffset - 2368)
|
||||||
|
*/
|
||||||
|
|
||||||
|
CopyOffset = ((accumulator >> 13) & 0xFFFF) + 2368;
|
||||||
|
printf("CopyOffset: %d\n", (int) CopyOffset);
|
||||||
|
|
||||||
|
BitStream_Shift(bs, 19);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* invalid encoding */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32* pSize)
|
UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32* pSize)
|
||||||
{
|
{
|
||||||
BYTE* pEnd;
|
BYTE* pEnd;
|
||||||
|
@ -80,32 +253,28 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32*
|
||||||
UINT32 MatchIndex;
|
UINT32 MatchIndex;
|
||||||
UINT32 accumulator;
|
UINT32 accumulator;
|
||||||
|
|
||||||
Flags = mppc->CompressionLevel;
|
|
||||||
|
|
||||||
BitStream_Attach(mppc->bs, pDstData, *pSize);
|
BitStream_Attach(mppc->bs, pDstData, *pSize);
|
||||||
|
|
||||||
if (((mppc->HistoryOffset + *pSize) < (mppc->HistoryBufferSize - 3)) /* && mppc->HistoryOffset */)
|
CopyMemory(&(mppc->HistoryBuffer[mppc->HistoryOffset]), pSrcData, *pSize);
|
||||||
|
|
||||||
|
mppc->HistoryPtr = 0;
|
||||||
|
mppc->pHistoryPtr = &(mppc->HistoryBuffer[mppc->HistoryPtr]);
|
||||||
|
|
||||||
|
if (((mppc->HistoryOffset + *pSize) < (mppc->HistoryBufferSize - 3)) && mppc->HistoryOffset)
|
||||||
{
|
{
|
||||||
/* SrcData fits into HistoryBuffer? (YES) */
|
Flags = mppc->CompressionLevel;
|
||||||
|
|
||||||
CopyMemory(&(mppc->HistoryBuffer[mppc->HistoryOffset]), pSrcData, *pSize);
|
|
||||||
|
|
||||||
mppc->HistoryPtr = 0;
|
|
||||||
mppc->pHistoryPtr = &(mppc->HistoryBuffer[mppc->HistoryPtr]);
|
|
||||||
|
|
||||||
mppc->HistoryOffset += *pSize;
|
|
||||||
mppc->pHistoryOffset = &(mppc->HistoryBuffer[mppc->HistoryOffset]);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* SrcData fits into HistoryBuffer? (NO) */
|
|
||||||
|
|
||||||
mppc->HistoryOffset = 0;
|
mppc->HistoryOffset = 0;
|
||||||
mppc->pHistoryOffset = &(mppc->HistoryBuffer[mppc->HistoryOffset]);
|
mppc->pHistoryOffset = &(mppc->HistoryBuffer[mppc->HistoryOffset]);
|
||||||
|
|
||||||
Flags |= PACKET_AT_FRONT;
|
Flags = PACKET_AT_FRONT | mppc->CompressionLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mppc->HistoryOffset += *pSize;
|
||||||
|
mppc->pHistoryOffset = &(mppc->HistoryBuffer[mppc->HistoryOffset]);
|
||||||
|
|
||||||
if (mppc->HistoryPtr < mppc->HistoryOffset)
|
if (mppc->HistoryPtr < mppc->HistoryOffset)
|
||||||
{
|
{
|
||||||
/* HistoryPtr < HistoryOffset? (YES) */
|
/* HistoryPtr < HistoryOffset? (YES) */
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
#include <winpr/print.h>
|
#include <winpr/print.h>
|
||||||
|
#include <winpr/bitstream.h>
|
||||||
|
|
||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
#include <freerdp/codec/mppc.h>
|
#include <freerdp/codec/mppc.h>
|
||||||
|
@ -684,9 +685,28 @@ int test_mppc_old()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char TEST_MPPC_BELL_TOLLS[] = "for.whom.the.bell.tolls,.the.bell.tolls.for.thee!";
|
/**
|
||||||
|
* for.whom.the.bell.tolls,.the.bell.tolls.for.thee!
|
||||||
|
* for.whom.the.bell.tolls,<16,15>.<40,4><19,3>e!
|
||||||
|
*/
|
||||||
|
|
||||||
int TestFreeRDPCodecMppc(int argc, char* argv[])
|
const BYTE TEST_MPPC_BELLS[] = "for.whom.the.bell.tolls,.the.bell.tolls.for.thee!";
|
||||||
|
|
||||||
|
/* Flags: 0x0060 Length: 33 */
|
||||||
|
|
||||||
|
const BYTE TEST_MPPC_BELLS_RDP4[] =
|
||||||
|
"\x66\x6f\x72\x2e\x77\x68\x6f\x6d\x2e\x74\x68\x65\x2e\x62\x65\x6c"
|
||||||
|
"\x6c\x2e\x74\x6f\x6c\x6c\x73\x2c\xf4\x37\x2e\x66\xfa\x1f\x19\x94"
|
||||||
|
"\x84";
|
||||||
|
|
||||||
|
/* Flags: 0x0061 Length: 34 */
|
||||||
|
|
||||||
|
const BYTE TEST_MPPC_BELLS_RDP5[] =
|
||||||
|
"\x66\x6f\x72\x2e\x77\x68\x6f\x6d\x2e\x74\x68\x65\x2e\x62\x65\x6c"
|
||||||
|
"\x6c\x2e\x74\x6f\x6c\x6c\x73\x2c\xfa\x1b\x97\x33\x7e\x87\xe3\x32"
|
||||||
|
"\x90\x80";
|
||||||
|
|
||||||
|
int test_MppcCompressBells()
|
||||||
{
|
{
|
||||||
UINT32 size;
|
UINT32 size;
|
||||||
UINT32 flags;
|
UINT32 flags;
|
||||||
|
@ -696,15 +716,75 @@ int TestFreeRDPCodecMppc(int argc, char* argv[])
|
||||||
|
|
||||||
mppc = mppc_context_new(1, TRUE);
|
mppc = mppc_context_new(1, TRUE);
|
||||||
|
|
||||||
#if 0
|
size = sizeof(TEST_MPPC_BELLS) - 1;
|
||||||
size = sizeof(TEST_MPPC_BELL_TOLLS) - 1;
|
pSrcData = (BYTE*) TEST_MPPC_BELLS;
|
||||||
pSrcData = (BYTE*) TEST_MPPC_BELL_TOLLS;
|
|
||||||
|
|
||||||
printf("%s\n", pSrcData);
|
printf("%s\n", pSrcData);
|
||||||
flags = mppc_compress(mppc, pSrcData, OutputBuffer, &size);
|
flags = mppc_compress(mppc, pSrcData, OutputBuffer, &size);
|
||||||
|
|
||||||
printf("flags: 0x%04X size: %d\n", flags, size);
|
printf("flags: 0x%04X size: %d\n", flags, size);
|
||||||
|
|
||||||
|
if (memcmp(OutputBuffer, TEST_MPPC_BELLS_RDP5, size) != 0)
|
||||||
|
{
|
||||||
|
printf("Actual:\n");
|
||||||
|
BitDump(OutputBuffer, size * 8, BITDUMP_MSB_FIRST);
|
||||||
|
|
||||||
|
printf("Expected:\n");
|
||||||
|
BitDump(TEST_MPPC_BELLS_RDP5, size * 8, BITDUMP_MSB_FIRST);
|
||||||
|
}
|
||||||
|
|
||||||
|
mppc_context_free(mppc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_MppcDecompressBells()
|
||||||
|
{
|
||||||
|
UINT32 size;
|
||||||
|
UINT32 flags;
|
||||||
|
BYTE* pSrcData;
|
||||||
|
MPPC_CONTEXT* mppc;
|
||||||
|
BYTE OutputBuffer[65536];
|
||||||
|
|
||||||
|
mppc = mppc_context_new(1, FALSE);
|
||||||
|
|
||||||
|
size = sizeof(TEST_MPPC_BELLS_RDP5) - 1;
|
||||||
|
pSrcData = (BYTE*) TEST_MPPC_BELLS_RDP5;
|
||||||
|
flags = PACKET_AT_FRONT | PACKET_COMPRESSED | 1;
|
||||||
|
|
||||||
|
flags = mppc_decompress(mppc, pSrcData, OutputBuffer, &size, flags);
|
||||||
|
|
||||||
|
printf("flags: 0x%04X size: %d\n", flags, size);
|
||||||
|
printf("%s\n", OutputBuffer);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
size = sizeof(TEST_MPPC_BELLS) - 1;
|
||||||
|
|
||||||
|
if (memcmp(OutputBuffer, TEST_MPPC_BELLS, sizeof(TEST_MPPC_BELLS) - 1) != 0)
|
||||||
|
{
|
||||||
|
printf("Actual:\n");
|
||||||
|
BitDump(OutputBuffer, size * 8, BITDUMP_MSB_FIRST);
|
||||||
|
|
||||||
|
printf("Expected:\n");
|
||||||
|
BitDump(TEST_MPPC_BELLS, size * 8, BITDUMP_MSB_FIRST);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
mppc_context_free(mppc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_MppcCompressBuffer()
|
||||||
|
{
|
||||||
|
UINT32 size;
|
||||||
|
UINT32 flags;
|
||||||
|
BYTE* pSrcData;
|
||||||
|
MPPC_CONTEXT* mppc;
|
||||||
|
BYTE OutputBuffer[65536];
|
||||||
|
|
||||||
|
mppc = mppc_context_new(1, TRUE);
|
||||||
|
|
||||||
size = sizeof(TEST_RDP5_UNCOMPRESSED_DATA);
|
size = sizeof(TEST_RDP5_UNCOMPRESSED_DATA);
|
||||||
pSrcData = (BYTE*) TEST_RDP5_UNCOMPRESSED_DATA;
|
pSrcData = (BYTE*) TEST_RDP5_UNCOMPRESSED_DATA;
|
||||||
|
|
||||||
|
@ -720,3 +800,11 @@ int TestFreeRDPCodecMppc(int argc, char* argv[])
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TestFreeRDPCodecMppc(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
//test_MppcCompressBells();
|
||||||
|
test_MppcDecompressBells();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* WinPR: Windows Portable Runtime
|
||||||
|
* BitStream Utils
|
||||||
|
*
|
||||||
|
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WINPR_UTILS_BITSTREAM_H
|
||||||
|
#define WINPR_UTILS_BITSTREAM_H
|
||||||
|
|
||||||
|
#include <winpr/winpr.h>
|
||||||
|
#include <winpr/wtypes.h>
|
||||||
|
|
||||||
|
#include <winpr/crt.h>
|
||||||
|
|
||||||
|
struct _wBitStream
|
||||||
|
{
|
||||||
|
BYTE* buffer;
|
||||||
|
BYTE* pointer;
|
||||||
|
DWORD position;
|
||||||
|
DWORD length;
|
||||||
|
DWORD capacity;
|
||||||
|
UINT32 mask;
|
||||||
|
UINT32 offset;
|
||||||
|
UINT32 prefetch;
|
||||||
|
UINT32 accumulator;
|
||||||
|
};
|
||||||
|
typedef struct _wBitStream wBitStream;
|
||||||
|
|
||||||
|
#define BitStream_Attach(_bs, _buffer, _capacity) { \
|
||||||
|
_bs->position = 0; \
|
||||||
|
_bs->buffer = _buffer; \
|
||||||
|
_bs->offset = 0; \
|
||||||
|
_bs->accumulator = 0; \
|
||||||
|
_bs->pointer = _bs->buffer; \
|
||||||
|
_bs->capacity = _capacity; \
|
||||||
|
_bs->length = _bs->capacity; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BitStream_Write_Bits(_bs, _bits, _nbits) { \
|
||||||
|
_bs->accumulator |= (_bits << _bs->offset); \
|
||||||
|
_bs->position += _nbits; \
|
||||||
|
_bs->offset += _nbits; \
|
||||||
|
if (_bs->offset >= 32) { \
|
||||||
|
*((UINT32*) _bs->pointer) = (_bs->accumulator); \
|
||||||
|
_bs->offset = _bs->offset - 32; \
|
||||||
|
_bs->accumulator = _bits >> (_nbits - _bs->offset); \
|
||||||
|
_bs->pointer += 4; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BitStream_Flush(_bs) { \
|
||||||
|
if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 3)) { \
|
||||||
|
*((UINT32*) _bs->pointer) = (_bs->accumulator); \
|
||||||
|
} else { \
|
||||||
|
if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 0)) \
|
||||||
|
*(_bs->pointer + 0) = (_bs->accumulator >> 0); \
|
||||||
|
if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 1)) \
|
||||||
|
*(_bs->pointer + 1) = (_bs->accumulator >> 8); \
|
||||||
|
if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 2)) \
|
||||||
|
*(_bs->pointer + 2) = (_bs->accumulator >> 16); \
|
||||||
|
if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 3)) \
|
||||||
|
*(_bs->pointer + 3) = (_bs->accumulator >> 24); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BITDUMP_MSB_FIRST 0x00000001
|
||||||
|
#define BITDUMP_STDERR 0x00000002
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WINPR_API void BitDump(const BYTE* buffer, UINT32 length, UINT32 flags);
|
||||||
|
|
||||||
|
WINPR_API wBitStream* BitStream_New();
|
||||||
|
WINPR_API void BitStream_Free(wBitStream* bs);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* WINPR_UTILS_BITSTREAM_H */
|
|
@ -27,6 +27,7 @@
|
||||||
#include <winpr/winpr.h>
|
#include <winpr/winpr.h>
|
||||||
#include <winpr/wtypes.h>
|
#include <winpr/wtypes.h>
|
||||||
|
|
||||||
|
#include <winpr/crt.h>
|
||||||
#include <winpr/synch.h>
|
#include <winpr/synch.h>
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
|
|
||||||
|
@ -596,65 +597,8 @@ WINPR_API int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* conte
|
||||||
WINPR_API wPubSub* PubSub_New(BOOL synchronized);
|
WINPR_API wPubSub* PubSub_New(BOOL synchronized);
|
||||||
WINPR_API void PubSub_Free(wPubSub* pubSub);
|
WINPR_API void PubSub_Free(wPubSub* pubSub);
|
||||||
|
|
||||||
/* BitStream */
|
|
||||||
|
|
||||||
struct _wBitStream
|
|
||||||
{
|
|
||||||
BYTE* buffer;
|
|
||||||
BYTE* pointer;
|
|
||||||
DWORD position;
|
|
||||||
DWORD length;
|
|
||||||
DWORD capacity;
|
|
||||||
UINT32 offset;
|
|
||||||
UINT32 accumulator;
|
|
||||||
};
|
|
||||||
typedef struct _wBitStream wBitStream;
|
|
||||||
|
|
||||||
#define BitStream_Attach(_bs, _buffer, _capacity) { \
|
|
||||||
_bs->position = 0; \
|
|
||||||
_bs->buffer = _buffer; \
|
|
||||||
_bs->offset = 0; \
|
|
||||||
_bs->accumulator = 0; \
|
|
||||||
_bs->pointer = _bs->buffer; \
|
|
||||||
_bs->capacity = _capacity; \
|
|
||||||
_bs->length = _bs->capacity; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BitStream_Write_Bits(_bs, _bits, _nbits) { \
|
|
||||||
_bs->accumulator |= (_bits << _bs->offset); \
|
|
||||||
_bs->position += _nbits; \
|
|
||||||
_bs->offset += _nbits; \
|
|
||||||
if (_bs->offset >= 32) { \
|
|
||||||
*(_bs->pointer + 0) = (_bs->accumulator >> 0); \
|
|
||||||
*(_bs->pointer + 1) = (_bs->accumulator >> 8); \
|
|
||||||
*(_bs->pointer + 2) = (_bs->accumulator >> 16); \
|
|
||||||
*(_bs->pointer + 3) = (_bs->accumulator >> 24); \
|
|
||||||
_bs->offset = _bs->offset - 32; \
|
|
||||||
_bs->accumulator = _bits >> (_nbits - _bs->offset); \
|
|
||||||
_bs->pointer += 4; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BitStream_Flush(_bs) { \
|
|
||||||
if ((_bs->pointer - _bs->buffer) > 0) \
|
|
||||||
*(_bs->pointer + 0) = (_bs->accumulator >> 0); \
|
|
||||||
if ((_bs->pointer - _bs->buffer) > 1) \
|
|
||||||
*(_bs->pointer + 1) = (_bs->accumulator >> 8); \
|
|
||||||
if ((_bs->pointer - _bs->buffer) > 2) \
|
|
||||||
*(_bs->pointer + 2) = (_bs->accumulator >> 16); \
|
|
||||||
if ((_bs->pointer - _bs->buffer) > 3) \
|
|
||||||
*(_bs->pointer + 3) = (_bs->accumulator >> 24); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BITDUMP_MSB_FIRST 0x00000001
|
|
||||||
#define BITDUMP_STDERR 0x00000002
|
|
||||||
|
|
||||||
WINPR_API void BitDump(BYTE* buffer, UINT32 length, UINT32 flags);
|
|
||||||
|
|
||||||
WINPR_API wBitStream* BitStream_New();
|
|
||||||
WINPR_API void BitStream_Free(wBitStream* bs);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* WINPR_COLLECTIONS_H */
|
#endif /* WINPR_COLLECTIONS_H */
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <winpr/collections.h>
|
#include <winpr/bitstream.h>
|
||||||
|
|
||||||
const char* BYTE_BIT_STRINGS_LSB[256] =
|
const char* BYTE_BIT_STRINGS_LSB[256] =
|
||||||
{
|
{
|
||||||
|
@ -159,7 +159,7 @@ const char* BYTE_BIT_STRINGS_MSB[256] =
|
||||||
"00111111", "10111111", "01111111", "11111111"
|
"00111111", "10111111", "01111111", "11111111"
|
||||||
};
|
};
|
||||||
|
|
||||||
void BitDump(BYTE* buffer, UINT32 length, UINT32 flags)
|
void BitDump(const BYTE* buffer, UINT32 length, UINT32 flags)
|
||||||
{
|
{
|
||||||
DWORD i;
|
DWORD i;
|
||||||
int nbits;
|
int nbits;
|
||||||
|
@ -174,6 +174,9 @@ void BitDump(BYTE* buffer, UINT32 length, UINT32 flags)
|
||||||
|
|
||||||
nbits = (length - i) > 8 ? 8 : (length - i);
|
nbits = (length - i) > 8 ? 8 : (length - i);
|
||||||
|
|
||||||
|
if ((i % 64) == 0)
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
printf("%.*s ", nbits, str);
|
printf("%.*s ", nbits, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
#include <winpr/print.h>
|
#include <winpr/print.h>
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
#include <winpr/collections.h>
|
#include <winpr/bitstream.h>
|
||||||
|
|
||||||
void BitStrGen()
|
void BitStrGen()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue