/* * Copyright (C) 2017-2018 Team Kodi * This file is part of Kodi - https://kodi.tv * * SPDX-License-Identifier: GPL-2.0-or-later * See LICENSES/README.md for more information. */ #include "BitstreamWriter.h" CBitstreamWriter::CBitstreamWriter(uint8_t *buffer, unsigned int buffer_size, int writer_le) : writer_le(writer_le) , bit_buf(0) , bit_left(32) , buf(buffer) , buf_ptr(buf) { } void CBitstreamWriter::WriteBits(int n, unsigned int value) { // Write up to 32 bits into a bitstream. unsigned int bit_buf; int bit_left; if (n == 32) { // Write exactly 32 bits into a bitstream. // danger, recursion in play. int lo = value & 0xffff; int hi = value >> 16; if (writer_le) { WriteBits(16, lo); WriteBits(16, hi); } else { WriteBits(16, hi); WriteBits(16, lo); } return; } bit_buf = this->bit_buf; bit_left = this->bit_left; if (writer_le) { bit_buf |= value << (32 - bit_left); if (n >= bit_left) { BS_WL32(buf_ptr, bit_buf); buf_ptr += 4; bit_buf = (bit_left == 32) ? 0 : value >> bit_left; bit_left += 32; } bit_left -= n; } else { if (n < bit_left) { bit_buf = (bit_buf << n) | value; bit_left -= n; } else { bit_buf <<= bit_left; bit_buf |= value >> (n - bit_left); BS_WB32(buf_ptr, bit_buf); buf_ptr += 4; bit_left += 32 - n; bit_buf = value; } } this->bit_buf = bit_buf; this->bit_left = bit_left; } void CBitstreamWriter::SkipBits(int n) { // Skip the given number of bits. // Must only be used if the actual values in the bitstream do not matter. // If n is 0 the behavior is undefined. bit_left -= n; buf_ptr -= 4 * (bit_left >> 5); bit_left &= 31; } void CBitstreamWriter::FlushBits() { if (!writer_le) { if (bit_left < 32) bit_buf <<= bit_left; } while (bit_left < 32) { if (writer_le) { *buf_ptr++ = bit_buf; bit_buf >>= 8; } else { *buf_ptr++ = bit_buf >> 24; bit_buf <<= 8; } bit_left += 8; } bit_left = 32; bit_buf = 0; }