/* * 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); }