Files
2025-10-12 09:13:56 +02:00

148 lines
2.7 KiB
C++

/*
* MCU renderer fontconv
* Bit writer
*
* (C) 2023 Gissio
*
* License: MIT
*/
#include "bitwriter.h"
BitWriter::BitWriter()
{
bitIndex = 0;
}
void BitWriter::clear()
{
data.clear();
bitIndex = 0;
}
void BitWriter::writeBit(bool value)
{
if (bitIndex == 0)
data.push_back(0);
data.back() |= (value << bitIndex);
bitIndex = (bitIndex + 1) & 0x7;
}
void BitWriter::writeFixedEncodedValue(uint32_t value, uint32_t bitNum)
{
while (bitNum--)
{
writeBit(value & 0x1);
value >>= 1;
}
}
void BitWriter::writeUnaryEncodedValue(uint32_t value)
{
while (value--)
writeBit(1);
writeBit(0);
}
void BitWriter::writeRiceEncodedValue(uint32_t value, uint32_t fixedBitNum)
{
uint32_t remainder = value & ((1 << fixedBitNum) - 1);
uint32_t quotient = value >> fixedBitNum;
writeFixedEncodedValue(remainder, fixedBitNum);
writeUnaryEncodedValue(quotient);
}
void BitWriter::writeByte(uint8_t value)
{
data.push_back(value);
bitIndex = 0;
}
void BitWriter::writeByte(uint32_t address, uint8_t value)
{
data[address] = value;
}
void BitWriter::writeShort(int16_t value)
{
data.push_back((value >> 8) & 0xff);
data.push_back((value >> 0) & 0xff);
bitIndex = 0;
}
void BitWriter::writeShort(uint32_t address, int16_t value)
{
data[address] = (value >> 8) & 0xff;
data[address + 1] = (value >> 0) & 0xff;
}
void BitWriter::writeVariableLengthWord(uint32_t value)
{
if (!value)
data.push_back(0);
else
{
for (int32_t shift = 28; shift >= 0; shift -= 7)
{
uint32_t shiftedValue = value >> shift;
if (!shiftedValue)
continue;
shiftedValue &= 0x7f;
if (shift)
shiftedValue |= 0x80;
data.push_back(shiftedValue);
}
}
bitIndex = 0;
}
void BitWriter::write(BitWriter &value)
{
if (bitIndex == 0)
{
data.insert(data.end(),
value.data.begin(),
value.data.end());
bitIndex = value.bitIndex;
}
else
{
for (size_t i = 0; i < value.getBitNum(); i++)
writeBit(value.readBit(i));
}
}
bool BitWriter::readBit(uint32_t bitIndex)
{
return data[bitIndex / 8] &
(1 << (bitIndex & 0x7));
}
uint32_t BitWriter::getBitNum()
{
uint32_t n = (uint32_t)data.size();
return (bitIndex == 0)
? (8 * n)
: (8 * (n - 1) + bitIndex);
}
uint32_t BitWriter::getCurrentAddress()
{
return (uint32_t)data.size();
}
bool BitWriter::operator!=(BitWriter &value)
{
return (bitIndex != value.bitIndex) ||
(data != value.data);
}