libfreerdp-codec: start MPPC compressor
This commit is contained in:
parent
77e91aa762
commit
d9a2fb4ff9
@ -45,6 +45,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
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 void mppc_context_free(MPPC_CONTEXT* mppc);
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/collections.h>
|
||||
#include <winpr/bitstream.h>
|
||||
|
||||
#include <freerdp/codec/mppc_enc.h>
|
||||
#include <freerdp/codec/mppc_dec.h>
|
||||
@ -72,6 +72,179 @@ const UINT32 MPPC_MATCH_TABLE[256] =
|
||||
|
||||
//#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)
|
||||
{
|
||||
BYTE* pEnd;
|
||||
@ -80,32 +253,28 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32*
|
||||
UINT32 MatchIndex;
|
||||
UINT32 accumulator;
|
||||
|
||||
Flags = mppc->CompressionLevel;
|
||||
|
||||
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) */
|
||||
|
||||
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]);
|
||||
Flags = mppc->CompressionLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SrcData fits into HistoryBuffer? (NO) */
|
||||
|
||||
mppc->HistoryOffset = 0;
|
||||
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)
|
||||
{
|
||||
/* HistoryPtr < HistoryOffset? (YES) */
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/bitstream.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/codec/mppc.h>
|
||||
@ -684,9 +685,28 @@ int test_mppc_old()
|
||||
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 flags;
|
||||
@ -696,15 +716,75 @@ int TestFreeRDPCodecMppc(int argc, char* argv[])
|
||||
|
||||
mppc = mppc_context_new(1, TRUE);
|
||||
|
||||
#if 0
|
||||
size = sizeof(TEST_MPPC_BELL_TOLLS) - 1;
|
||||
pSrcData = (BYTE*) TEST_MPPC_BELL_TOLLS;
|
||||
size = sizeof(TEST_MPPC_BELLS) - 1;
|
||||
pSrcData = (BYTE*) TEST_MPPC_BELLS;
|
||||
|
||||
printf("%s\n", pSrcData);
|
||||
flags = mppc_compress(mppc, pSrcData, OutputBuffer, &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
|
||||
|
||||
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);
|
||||
pSrcData = (BYTE*) TEST_RDP5_UNCOMPRESSED_DATA;
|
||||
|
||||
@ -720,3 +800,11 @@ int TestFreeRDPCodecMppc(int argc, char* argv[])
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TestFreeRDPCodecMppc(int argc, char* argv[])
|
||||
{
|
||||
//test_MppcCompressBells();
|
||||
test_MppcDecompressBells();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
95
winpr/include/winpr/bitstream.h
Normal file
95
winpr/include/winpr/bitstream.h
Normal file
@ -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/wtypes.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.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 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
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_COLLECTIONS_H */
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <winpr/collections.h>
|
||||
#include <winpr/bitstream.h>
|
||||
|
||||
const char* BYTE_BIT_STRINGS_LSB[256] =
|
||||
{
|
||||
@ -159,7 +159,7 @@ const char* BYTE_BIT_STRINGS_MSB[256] =
|
||||
"00111111", "10111111", "01111111", "11111111"
|
||||
};
|
||||
|
||||
void BitDump(BYTE* buffer, UINT32 length, UINT32 flags)
|
||||
void BitDump(const BYTE* buffer, UINT32 length, UINT32 flags)
|
||||
{
|
||||
DWORD i;
|
||||
int nbits;
|
||||
@ -174,6 +174,9 @@ void BitDump(BYTE* buffer, UINT32 length, UINT32 flags)
|
||||
|
||||
nbits = (length - i) > 8 ? 8 : (length - i);
|
||||
|
||||
if ((i % 64) == 0)
|
||||
printf("\n");
|
||||
|
||||
printf("%.*s ", nbits, str);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/collections.h>
|
||||
#include <winpr/bitstream.h>
|
||||
|
||||
void BitStrGen()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user