|
Packit Service |
fa4841 |
/*
|
|
Packit Service |
fa4841 |
* WinPR: Windows Portable Runtime
|
|
Packit Service |
fa4841 |
* BitStream Utils
|
|
Packit Service |
fa4841 |
*
|
|
Packit Service |
fa4841 |
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
|
Packit Service |
fa4841 |
*
|
|
Packit Service |
fa4841 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
Packit Service |
fa4841 |
* you may not use this file except in compliance with the License.
|
|
Packit Service |
fa4841 |
* You may obtain a copy of the License at
|
|
Packit Service |
fa4841 |
*
|
|
Packit Service |
fa4841 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit Service |
fa4841 |
*
|
|
Packit Service |
fa4841 |
* Unless required by applicable law or agreed to in writing, software
|
|
Packit Service |
fa4841 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit Service |
fa4841 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit Service |
fa4841 |
* See the License for the specific language governing permissions and
|
|
Packit Service |
fa4841 |
* limitations under the License.
|
|
Packit Service |
fa4841 |
*/
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
#ifndef WINPR_UTILS_BITSTREAM_H
|
|
Packit Service |
fa4841 |
#define WINPR_UTILS_BITSTREAM_H
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
#include <winpr/winpr.h>
|
|
Packit Service |
fa4841 |
#include <winpr/wtypes.h>
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
#include <winpr/crt.h>
|
|
Packit Service |
fa4841 |
#include <winpr/wlog.h>
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
struct _wBitStream
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
const BYTE* buffer;
|
|
Packit Service |
fa4841 |
BYTE* pointer;
|
|
Packit Service |
b1ea74 |
UINT32 position;
|
|
Packit Service |
b1ea74 |
UINT32 length;
|
|
Packit Service |
b1ea74 |
UINT32 capacity;
|
|
Packit Service |
fa4841 |
UINT32 mask;
|
|
Packit Service |
fa4841 |
UINT32 offset;
|
|
Packit Service |
fa4841 |
UINT32 prefetch;
|
|
Packit Service |
fa4841 |
UINT32 accumulator;
|
|
Packit Service |
fa4841 |
};
|
|
Packit Service |
fa4841 |
typedef struct _wBitStream wBitStream;
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
b1ea74 |
#define BITDUMP_MSB_FIRST 0x00000001
|
|
Packit Service |
b1ea74 |
#define BITDUMP_STDERR 0x00000002
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
#ifdef __cplusplus
|
|
Packit Service |
b1ea74 |
extern "C"
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
fa4841 |
#endif
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
b1ea74 |
static INLINE void BitStream_Prefetch(wBitStream* _bs)
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
(_bs->prefetch) = 0;
|
|
Packit Service |
b1ea74 |
if (((UINT32)(_bs->pointer - _bs->buffer) + 4) < (_bs->capacity))
|
|
Packit Service |
b1ea74 |
(_bs->prefetch) |= ((UINT32) * (_bs->pointer + 4) << 24);
|
|
Packit Service |
b1ea74 |
if (((UINT32)(_bs->pointer - _bs->buffer) + 5) < (_bs->capacity))
|
|
Packit Service |
b1ea74 |
(_bs->prefetch) |= ((UINT32) * (_bs->pointer + 5) << 16);
|
|
Packit Service |
b1ea74 |
if (((UINT32)(_bs->pointer - _bs->buffer) + 6) < (_bs->capacity))
|
|
Packit Service |
b1ea74 |
(_bs->prefetch) |= ((UINT32) * (_bs->pointer + 6) << 8);
|
|
Packit Service |
b1ea74 |
if (((UINT32)(_bs->pointer - _bs->buffer) + 7) < (_bs->capacity))
|
|
Packit Service |
b1ea74 |
(_bs->prefetch) |= ((UINT32) * (_bs->pointer + 7) << 0);
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
|
|
Packit Service |
b1ea74 |
static INLINE void BitStream_Fetch(wBitStream* _bs)
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
(_bs->accumulator) = 0;
|
|
Packit Service |
b1ea74 |
if (((UINT32)(_bs->pointer - _bs->buffer) + 0) < (_bs->capacity))
|
|
Packit Service |
b1ea74 |
(_bs->accumulator) |= ((UINT32) * (_bs->pointer + 0) << 24);
|
|
Packit Service |
b1ea74 |
if (((UINT32)(_bs->pointer - _bs->buffer) + 1) < (_bs->capacity))
|
|
Packit Service |
b1ea74 |
(_bs->accumulator) |= ((UINT32) * (_bs->pointer + 1) << 16);
|
|
Packit Service |
b1ea74 |
if (((UINT32)(_bs->pointer - _bs->buffer) + 2) < (_bs->capacity))
|
|
Packit Service |
b1ea74 |
(_bs->accumulator) |= ((UINT32) * (_bs->pointer + 2) << 8);
|
|
Packit Service |
b1ea74 |
if (((UINT32)(_bs->pointer - _bs->buffer) + 3) < (_bs->capacity))
|
|
Packit Service |
b1ea74 |
(_bs->accumulator) |= ((UINT32) * (_bs->pointer + 3) << 0);
|
|
Packit Service |
b1ea74 |
BitStream_Prefetch(_bs);
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
|
|
Packit Service |
b1ea74 |
static INLINE void BitStream_Flush(wBitStream* _bs)
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
if (((UINT32)(_bs->pointer - _bs->buffer) + 0) < (_bs->capacity))
|
|
Packit Service |
b1ea74 |
*(_bs->pointer + 0) = ((UINT32)_bs->accumulator >> 24);
|
|
Packit Service |
b1ea74 |
if (((UINT32)(_bs->pointer - _bs->buffer) + 1) < (_bs->capacity))
|
|
Packit Service |
b1ea74 |
*(_bs->pointer + 1) = ((UINT32)_bs->accumulator >> 16);
|
|
Packit Service |
b1ea74 |
if (((UINT32)(_bs->pointer - _bs->buffer) + 2) < (_bs->capacity))
|
|
Packit Service |
b1ea74 |
*(_bs->pointer + 2) = ((UINT32)_bs->accumulator >> 8);
|
|
Packit Service |
b1ea74 |
if (((UINT32)(_bs->pointer - _bs->buffer) + 3) < (_bs->capacity))
|
|
Packit Service |
b1ea74 |
*(_bs->pointer + 3) = ((UINT32)_bs->accumulator >> 0);
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
|
|
Packit Service |
b1ea74 |
static INLINE void BitStream_Shift(wBitStream* _bs, UINT32 _nbits)
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
if (_nbits == 0)
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
else if ((_nbits > 0) && (_nbits < 32))
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
_bs->accumulator <<= _nbits;
|
|
Packit Service |
b1ea74 |
_bs->position += _nbits;
|
|
Packit Service |
b1ea74 |
_bs->offset += _nbits;
|
|
Packit Service |
b1ea74 |
if (_bs->offset < 32)
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
_bs->mask = ((1UL << _nbits) - 1);
|
|
Packit Service |
b1ea74 |
_bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask);
|
|
Packit Service |
b1ea74 |
_bs->prefetch <<= _nbits;
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
else
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
_bs->mask = ((1UL << _nbits) - 1);
|
|
Packit Service |
b1ea74 |
_bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask);
|
|
Packit Service |
b1ea74 |
_bs->prefetch <<= _nbits;
|
|
Packit Service |
b1ea74 |
_bs->offset -= 32;
|
|
Packit Service |
b1ea74 |
_bs->pointer += 4;
|
|
Packit Service |
b1ea74 |
BitStream_Prefetch(_bs);
|
|
Packit Service |
b1ea74 |
if (_bs->offset)
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
_bs->mask = ((1UL << _bs->offset) - 1);
|
|
Packit Service |
b1ea74 |
_bs->accumulator |= ((_bs->prefetch >> (32 - _bs->offset)) & _bs->mask);
|
|
Packit Service |
b1ea74 |
_bs->prefetch <<= _bs->offset;
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
else
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
WLog_WARN("com.winpr.bitstream", "warning: BitStream_Shift(%u)", (unsigned)_nbits);
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
|
|
Packit Service |
b1ea74 |
static INLINE void BitStream_Shift32(wBitStream* _bs)
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
BitStream_Shift(_bs, 16);
|
|
Packit Service |
b1ea74 |
BitStream_Shift(_bs, 16);
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
|
|
Packit Service |
b1ea74 |
static INLINE void BitStream_Write_Bits(wBitStream* _bs, UINT32 _bits, UINT32 _nbits)
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
_bs->position += _nbits;
|
|
Packit Service |
b1ea74 |
_bs->offset += _nbits;
|
|
Packit Service |
b1ea74 |
if (_bs->offset < 32)
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
_bs->accumulator |= (_bits << (32 - _bs->offset));
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
else
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
_bs->offset -= 32;
|
|
Packit Service |
b1ea74 |
_bs->mask = ((1 << (_nbits - _bs->offset)) - 1);
|
|
Packit Service |
b1ea74 |
_bs->accumulator |= ((_bits >> _bs->offset) & _bs->mask);
|
|
Packit Service |
b1ea74 |
BitStream_Flush(_bs);
|
|
Packit Service |
b1ea74 |
_bs->accumulator = 0;
|
|
Packit Service |
b1ea74 |
_bs->pointer += 4;
|
|
Packit Service |
b1ea74 |
if (_bs->offset)
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
_bs->mask = ((1UL << _bs->offset) - 1);
|
|
Packit Service |
b1ea74 |
_bs->accumulator |= ((_bits & _bs->mask) << (32 - _bs->offset));
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
|
|
Packit Service |
b1ea74 |
static INLINE size_t BitStream_GetRemainingLength(wBitStream* _bs)
|
|
Packit Service |
b1ea74 |
{
|
|
Packit Service |
b1ea74 |
return (_bs->length - _bs->position);
|
|
Packit Service |
b1ea74 |
}
|
|
Packit Service |
b1ea74 |
|
|
Packit Service |
b1ea74 |
WINPR_API void BitDump(const char* tag, UINT32 level, const BYTE* buffer, UINT32 length,
|
|
Packit Service |
b1ea74 |
UINT32 flags);
|
|
Packit Service |
b1ea74 |
WINPR_API UINT32 ReverseBits32(UINT32 bits, UINT32 nbits);
|
|
Packit Service |
b1ea74 |
|
|
Packit Service |
b1ea74 |
WINPR_API void BitStream_Attach(wBitStream* bs, const BYTE* buffer, UINT32 capacity);
|
|
Packit Service |
b1ea74 |
|
|
Packit Service |
b1ea74 |
WINPR_API wBitStream* BitStream_New();
|
|
Packit Service |
b1ea74 |
WINPR_API void BitStream_Free(wBitStream* bs);
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
#ifdef __cplusplus
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
#endif
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
#endif /* WINPR_UTILS_BITSTREAM_H */
|