20#ifndef WINPR_UTILS_BITSTREAM_H
21#define WINPR_UTILS_BITSTREAM_H
23#include <winpr/assert.h>
24#include <winpr/winpr.h>
25#include <winpr/wtypes.h>
28#include <winpr/wlog.h>
43#define BITDUMP_MSB_FIRST 0x00000001
44#define BITDUMP_STDERR 0x00000002
51 static INLINE
void BitStream_Prefetch(
wBitStream* _bs)
57 const intptr_t diff = _bs->pointer - _bs->buffer;
58 if ((diff + 4) < (intptr_t)_bs->capacity)
59 (_bs->prefetch) |= ((UINT32)_bs->pointer[4] << 24);
60 if ((diff + 5) < (intptr_t)_bs->capacity)
61 (_bs->prefetch) |= ((UINT32)_bs->pointer[5] << 16);
62 if ((diff + 6) < (intptr_t)_bs->capacity)
63 (_bs->prefetch) |= ((UINT32)_bs->pointer[6] << 8);
64 if ((diff + 7) < (intptr_t)_bs->capacity)
65 (_bs->prefetch) |= ((UINT32)_bs->pointer[7] << 0);
68 static INLINE
void BitStream_Fetch(
wBitStream* _bs)
71 (_bs->accumulator) = 0;
73 const intptr_t diff = _bs->pointer - _bs->buffer;
74 if ((diff + 0) < (intptr_t)_bs->capacity)
75 (_bs->accumulator) |= ((UINT32)_bs->pointer[0] << 24);
76 if ((diff + 1) < (intptr_t)_bs->capacity)
77 (_bs->accumulator) |= ((UINT32)_bs->pointer[1] << 16);
78 if ((diff + 2) < (intptr_t)_bs->capacity)
79 (_bs->accumulator) |= ((UINT32)_bs->pointer[2] << 8);
80 if ((diff + 3) < (intptr_t)_bs->capacity)
81 (_bs->accumulator) |= ((UINT32)_bs->pointer[3] << 0);
82 BitStream_Prefetch(_bs);
85 static INLINE
void BitStream_Flush(
wBitStream* _bs)
88 const intptr_t diff = _bs->pointer - _bs->buffer;
89 if ((diff + 0) < (intptr_t)_bs->capacity)
90 _bs->pointer[0] = (_bs->accumulator >> 24) & 0xFF;
91 if ((diff + 1) < (intptr_t)_bs->capacity)
92 _bs->pointer[1] = (_bs->accumulator >> 16) & 0xFF;
93 if ((diff + 2) < (intptr_t)_bs->capacity)
94 _bs->pointer[2] = (_bs->accumulator >> 8) & 0xFF;
95 if ((diff + 3) < (intptr_t)_bs->capacity)
96 _bs->pointer[3] = (_bs->accumulator >> 0) & 0xFF;
99 static INLINE
void BitStream_Shift(
wBitStream* _bs, UINT32 _nbits)
105 else if ((_nbits > 0) && (_nbits < 32))
107 _bs->accumulator <<= _nbits;
108 _bs->position += _nbits;
109 _bs->offset += _nbits;
110 if (_bs->offset < 32)
112 _bs->mask = (UINT32)((1UL << _nbits) - 1UL);
113 _bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask);
114 _bs->prefetch <<= _nbits;
118 _bs->mask = (UINT32)((1UL << _nbits) - 1UL);
119 _bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask);
120 _bs->prefetch <<= _nbits;
123 BitStream_Prefetch(_bs);
126 _bs->mask = (UINT32)((1UL << _bs->offset) - 1UL);
127 _bs->accumulator |= ((_bs->prefetch >> (32 - _bs->offset)) & _bs->mask);
128 _bs->prefetch <<= _bs->offset;
134 WLog_WARN(
"com.winpr.bitstream",
"warning: BitStream_Shift(%u)", (
unsigned)_nbits);
138 static INLINE
void BitStream_Shift32(
wBitStream* _bs)
141 BitStream_Shift(_bs, 16);
142 BitStream_Shift(_bs, 16);
145 static INLINE
void BitStream_Write_Bits(
wBitStream* _bs, UINT32 _bits, UINT32 _nbits)
148 _bs->position += _nbits;
149 _bs->offset += _nbits;
150 if (_bs->offset < 32)
152 _bs->accumulator |= (_bits << (32 - _bs->offset));
157 _bs->mask = ((1 << (_nbits - _bs->offset)) - 1);
158 _bs->accumulator |= ((_bits >> _bs->offset) & _bs->mask);
159 BitStream_Flush(_bs);
160 _bs->accumulator = 0;
164 _bs->mask = (UINT32)((1UL << _bs->offset) - 1);
165 _bs->accumulator |= ((_bits & _bs->mask) << (32 - _bs->offset));
170 static INLINE
size_t BitStream_GetRemainingLength(
wBitStream* _bs)
173 return (_bs->length - _bs->position);
176 WINPR_API
void BitDump(
const char* tag, UINT32 level,
const BYTE* buffer, UINT32 length,
178 WINPR_API UINT32 ReverseBits32(UINT32 bits, UINT32 nbits);
180 WINPR_API
void BitStream_Attach(
wBitStream* bs,
const BYTE* buffer, UINT32 capacity);
182 WINPR_API
void BitStream_Free(
wBitStream* bs);
184 WINPR_ATTR_MALLOC(BitStream_Free, 1)