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>
27 #include <winpr/crt.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)
56 if (((UINT32)(_bs->pointer - _bs->buffer) + 4) < (_bs->capacity))
57 (_bs->prefetch) |= ((UINT32) * (_bs->pointer + 4) << 24);
58 if (((UINT32)(_bs->pointer - _bs->buffer) + 5) < (_bs->capacity))
59 (_bs->prefetch) |= ((UINT32) * (_bs->pointer + 5) << 16);
60 if (((UINT32)(_bs->pointer - _bs->buffer) + 6) < (_bs->capacity))
61 (_bs->prefetch) |= ((UINT32) * (_bs->pointer + 6) << 8);
62 if (((UINT32)(_bs->pointer - _bs->buffer) + 7) < (_bs->capacity))
63 (_bs->prefetch) |= ((UINT32) * (_bs->pointer + 7) << 0);
66 static INLINE
void BitStream_Fetch(
wBitStream* _bs)
69 (_bs->accumulator) = 0;
70 if (((UINT32)(_bs->pointer - _bs->buffer) + 0) < (_bs->capacity))
71 (_bs->accumulator) |= ((UINT32) * (_bs->pointer + 0) << 24);
72 if (((UINT32)(_bs->pointer - _bs->buffer) + 1) < (_bs->capacity))
73 (_bs->accumulator) |= ((UINT32) * (_bs->pointer + 1) << 16);
74 if (((UINT32)(_bs->pointer - _bs->buffer) + 2) < (_bs->capacity))
75 (_bs->accumulator) |= ((UINT32) * (_bs->pointer + 2) << 8);
76 if (((UINT32)(_bs->pointer - _bs->buffer) + 3) < (_bs->capacity))
77 (_bs->accumulator) |= ((UINT32) * (_bs->pointer + 3) << 0);
78 BitStream_Prefetch(_bs);
81 static INLINE
void BitStream_Flush(
wBitStream* _bs)
84 if (((UINT32)(_bs->pointer - _bs->buffer) + 0) < (_bs->capacity))
85 *(_bs->pointer + 0) = (BYTE)((UINT32)_bs->accumulator >> 24);
86 if (((UINT32)(_bs->pointer - _bs->buffer) + 1) < (_bs->capacity))
87 *(_bs->pointer + 1) = (BYTE)((UINT32)_bs->accumulator >> 16);
88 if (((UINT32)(_bs->pointer - _bs->buffer) + 2) < (_bs->capacity))
89 *(_bs->pointer + 2) = (BYTE)((UINT32)_bs->accumulator >> 8);
90 if (((UINT32)(_bs->pointer - _bs->buffer) + 3) < (_bs->capacity))
91 *(_bs->pointer + 3) = (BYTE)((UINT32)_bs->accumulator >> 0);
94 static INLINE
void BitStream_Shift(
wBitStream* _bs, UINT32 _nbits)
100 else if ((_nbits > 0) && (_nbits < 32))
102 _bs->accumulator <<= _nbits;
103 _bs->position += _nbits;
104 _bs->offset += _nbits;
105 if (_bs->offset < 32)
107 _bs->mask = (UINT32)((1UL << _nbits) - 1UL);
108 _bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask);
109 _bs->prefetch <<= _nbits;
113 _bs->mask = (UINT32)((1UL << _nbits) - 1UL);
114 _bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask);
115 _bs->prefetch <<= _nbits;
118 BitStream_Prefetch(_bs);
121 _bs->mask = (UINT32)((1UL << _bs->offset) - 1UL);
122 _bs->accumulator |= ((_bs->prefetch >> (32 - _bs->offset)) & _bs->mask);
123 _bs->prefetch <<= _bs->offset;
129 WLog_WARN(
"com.winpr.bitstream",
"warning: BitStream_Shift(%u)", (
unsigned)_nbits);
133 static INLINE
void BitStream_Shift32(
wBitStream* _bs)
136 BitStream_Shift(_bs, 16);
137 BitStream_Shift(_bs, 16);
140 static INLINE
void BitStream_Write_Bits(
wBitStream* _bs, UINT32 _bits, UINT32 _nbits)
143 _bs->position += _nbits;
144 _bs->offset += _nbits;
145 if (_bs->offset < 32)
147 _bs->accumulator |= (_bits << (32 - _bs->offset));
152 _bs->mask = ((1 << (_nbits - _bs->offset)) - 1);
153 _bs->accumulator |= ((_bits >> _bs->offset) & _bs->mask);
154 BitStream_Flush(_bs);
155 _bs->accumulator = 0;
159 _bs->mask = (UINT32)((1UL << _bs->offset) - 1);
160 _bs->accumulator |= ((_bits & _bs->mask) << (32 - _bs->offset));
165 static INLINE
size_t BitStream_GetRemainingLength(
wBitStream* _bs)
168 return (_bs->length - _bs->position);
171 WINPR_API
void BitDump(
const char* tag, UINT32 level,
const BYTE* buffer, UINT32 length,
173 WINPR_API UINT32 ReverseBits32(UINT32 bits, UINT32 nbits);
175 WINPR_API
void BitStream_Attach(
wBitStream* bs,
const BYTE* buffer, UINT32 capacity);
177 WINPR_API
void BitStream_Free(
wBitStream* bs);
179 WINPR_ATTR_MALLOC(BitStream_Free, 1)