vulkan-playground/bitstream.h
2024-10-12 02:20:47 +03:00

102 lines
1.9 KiB
C++

#ifndef BITSTREAM_H
#define BITSTREAM_H
#include <stdlib.h>
template <int max_size_in_dword>
struct BaseBitstream
{
int bit_offset = 0;
unsigned int buffer[max_size_in_dword];
static unsigned int Swap32(unsigned int val)
{
unsigned char *pval = (unsigned char *)&val;
return ((pval[0] << 24) |
(pval[1] << 16) |
(pval[2] << 8) |
(pval[3] << 0));
}
inline void End()
{
int pos = (bit_offset >> 5);
int orig_bit_offset = (bit_offset & 0x1f);
int bit_left = 32 - orig_bit_offset;
if (orig_bit_offset) {
buffer[pos] = Swap32((buffer[pos] << bit_left));
}
}
inline void PutUI(unsigned int val, int size_in_bits)
{
int pos = (bit_offset >> 5);
int orig_bit_offset = (bit_offset & 0x1f);
int bit_left = 32 - orig_bit_offset;
if (!size_in_bits)
return;
bit_offset += size_in_bits;
if (bit_left > size_in_bits) {
buffer[pos] = (buffer[pos] << size_in_bits | val);
} else {
size_in_bits -= bit_left;
buffer[pos] = (buffer[pos] << bit_left) | (val >> size_in_bits);
buffer[pos] = Swap32(buffer[pos]);
if (pos + 1 == max_size_in_dword) {
abort();
}
buffer[pos + 1] = val;
}
}
inline void PutUE(unsigned int val)
{
int size_in_bits = 0;
int tmp_val = ++val;
while (tmp_val) {
tmp_val >>= 1;
size_in_bits++;
}
PutUI(0, size_in_bits - 1); /* leading zero */
PutUI(val, size_in_bits);
}
inline void PutSE(int val)
{
unsigned int new_val;
if (val <= 0)
new_val = -2 * val;
else
new_val = 2 * val - 1;
PutUE(new_val);
}
inline void ByteAligning(int bit)
{
int orig_bit_offset = (bit_offset & 0x7);
int bit_left = 8 - orig_bit_offset;
int new_val;
if (!orig_bit_offset)
return;
if (bit)
new_val = (1 << bit_left) - 1;
else
new_val = 0;
PutUI(new_val, bit_left);
}
inline void RBSPTrailingBits()
{
PutUI(1, 1);
ByteAligning(0);
}
};
#endif // BITSTREAM_H