148 lines
2.7 KiB
C++
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);
|
|
}
|