cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

bitstream.h (5197B)


      1/*
      2 * WinPR: Windows Portable Runtime
      3 * BitStream Utils
      4 *
      5 * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
      6 *
      7 * Licensed under the Apache License, Version 2.0 (the "License");
      8 * you may not use this file except in compliance with the License.
      9 * You may obtain a copy of the License at
     10 *
     11 *     http://www.apache.org/licenses/LICENSE-2.0
     12 *
     13 * Unless required by applicable law or agreed to in writing, software
     14 * distributed under the License is distributed on an "AS IS" BASIS,
     15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 * See the License for the specific language governing permissions and
     17 * limitations under the License.
     18 */
     19
     20#ifndef WINPR_UTILS_BITSTREAM_H
     21#define WINPR_UTILS_BITSTREAM_H
     22
     23#include <winpr/winpr.h>
     24#include <winpr/wtypes.h>
     25
     26#include <winpr/crt.h>
     27#include <winpr/wlog.h>
     28
     29struct _wBitStream
     30{
     31	const BYTE* buffer;
     32	BYTE* pointer;
     33	UINT32 position;
     34	UINT32 length;
     35	UINT32 capacity;
     36	UINT32 mask;
     37	UINT32 offset;
     38	UINT32 prefetch;
     39	UINT32 accumulator;
     40};
     41typedef struct _wBitStream wBitStream;
     42
     43#define BITDUMP_MSB_FIRST 0x00000001
     44#define BITDUMP_STDERR 0x00000002
     45
     46#ifdef __cplusplus
     47extern "C"
     48{
     49#endif
     50
     51	static INLINE void BitStream_Prefetch(wBitStream* _bs)
     52	{
     53		(_bs->prefetch) = 0;
     54		if (((UINT32)(_bs->pointer - _bs->buffer) + 4) < (_bs->capacity))
     55			(_bs->prefetch) |= ((UINT32) * (_bs->pointer + 4) << 24);
     56		if (((UINT32)(_bs->pointer - _bs->buffer) + 5) < (_bs->capacity))
     57			(_bs->prefetch) |= ((UINT32) * (_bs->pointer + 5) << 16);
     58		if (((UINT32)(_bs->pointer - _bs->buffer) + 6) < (_bs->capacity))
     59			(_bs->prefetch) |= ((UINT32) * (_bs->pointer + 6) << 8);
     60		if (((UINT32)(_bs->pointer - _bs->buffer) + 7) < (_bs->capacity))
     61			(_bs->prefetch) |= ((UINT32) * (_bs->pointer + 7) << 0);
     62	}
     63
     64	static INLINE void BitStream_Fetch(wBitStream* _bs)
     65	{
     66		(_bs->accumulator) = 0;
     67		if (((UINT32)(_bs->pointer - _bs->buffer) + 0) < (_bs->capacity))
     68			(_bs->accumulator) |= ((UINT32) * (_bs->pointer + 0) << 24);
     69		if (((UINT32)(_bs->pointer - _bs->buffer) + 1) < (_bs->capacity))
     70			(_bs->accumulator) |= ((UINT32) * (_bs->pointer + 1) << 16);
     71		if (((UINT32)(_bs->pointer - _bs->buffer) + 2) < (_bs->capacity))
     72			(_bs->accumulator) |= ((UINT32) * (_bs->pointer + 2) << 8);
     73		if (((UINT32)(_bs->pointer - _bs->buffer) + 3) < (_bs->capacity))
     74			(_bs->accumulator) |= ((UINT32) * (_bs->pointer + 3) << 0);
     75		BitStream_Prefetch(_bs);
     76	}
     77
     78	static INLINE void BitStream_Flush(wBitStream* _bs)
     79	{
     80		if (((UINT32)(_bs->pointer - _bs->buffer) + 0) < (_bs->capacity))
     81			*(_bs->pointer + 0) = ((UINT32)_bs->accumulator >> 24);
     82		if (((UINT32)(_bs->pointer - _bs->buffer) + 1) < (_bs->capacity))
     83			*(_bs->pointer + 1) = ((UINT32)_bs->accumulator >> 16);
     84		if (((UINT32)(_bs->pointer - _bs->buffer) + 2) < (_bs->capacity))
     85			*(_bs->pointer + 2) = ((UINT32)_bs->accumulator >> 8);
     86		if (((UINT32)(_bs->pointer - _bs->buffer) + 3) < (_bs->capacity))
     87			*(_bs->pointer + 3) = ((UINT32)_bs->accumulator >> 0);
     88	}
     89
     90	static INLINE void BitStream_Shift(wBitStream* _bs, UINT32 _nbits)
     91	{
     92		if (_nbits == 0)
     93		{
     94		}
     95		else if ((_nbits > 0) && (_nbits < 32))
     96		{
     97			_bs->accumulator <<= _nbits;
     98			_bs->position += _nbits;
     99			_bs->offset += _nbits;
    100			if (_bs->offset < 32)
    101			{
    102				_bs->mask = ((1UL << _nbits) - 1);
    103				_bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask);
    104				_bs->prefetch <<= _nbits;
    105			}
    106			else
    107			{
    108				_bs->mask = ((1UL << _nbits) - 1);
    109				_bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask);
    110				_bs->prefetch <<= _nbits;
    111				_bs->offset -= 32;
    112				_bs->pointer += 4;
    113				BitStream_Prefetch(_bs);
    114				if (_bs->offset)
    115				{
    116					_bs->mask = ((1UL << _bs->offset) - 1);
    117					_bs->accumulator |= ((_bs->prefetch >> (32 - _bs->offset)) & _bs->mask);
    118					_bs->prefetch <<= _bs->offset;
    119				}
    120			}
    121		}
    122		else
    123		{
    124			WLog_WARN("com.winpr.bitstream", "warning: BitStream_Shift(%u)", (unsigned)_nbits);
    125		}
    126	}
    127
    128	static INLINE void BitStream_Shift32(wBitStream* _bs)
    129	{
    130		BitStream_Shift(_bs, 16);
    131		BitStream_Shift(_bs, 16);
    132	}
    133
    134	static INLINE void BitStream_Write_Bits(wBitStream* _bs, UINT32 _bits, UINT32 _nbits)
    135	{
    136		_bs->position += _nbits;
    137		_bs->offset += _nbits;
    138		if (_bs->offset < 32)
    139		{
    140			_bs->accumulator |= (_bits << (32 - _bs->offset));
    141		}
    142		else
    143		{
    144			_bs->offset -= 32;
    145			_bs->mask = ((1 << (_nbits - _bs->offset)) - 1);
    146			_bs->accumulator |= ((_bits >> _bs->offset) & _bs->mask);
    147			BitStream_Flush(_bs);
    148			_bs->accumulator = 0;
    149			_bs->pointer += 4;
    150			if (_bs->offset)
    151			{
    152				_bs->mask = ((1UL << _bs->offset) - 1);
    153				_bs->accumulator |= ((_bits & _bs->mask) << (32 - _bs->offset));
    154			}
    155		}
    156	}
    157
    158	static INLINE size_t BitStream_GetRemainingLength(wBitStream* _bs)
    159	{
    160		return (_bs->length - _bs->position);
    161	}
    162
    163	WINPR_API void BitDump(const char* tag, UINT32 level, const BYTE* buffer, UINT32 length,
    164	                       UINT32 flags);
    165	WINPR_API UINT32 ReverseBits32(UINT32 bits, UINT32 nbits);
    166
    167	WINPR_API void BitStream_Attach(wBitStream* bs, const BYTE* buffer, UINT32 capacity);
    168
    169	WINPR_API wBitStream* BitStream_New();
    170	WINPR_API void BitStream_Free(wBitStream* bs);
    171
    172#ifdef __cplusplus
    173}
    174#endif
    175
    176#endif /* WINPR_UTILS_BITSTREAM_H */