bool readReference(IBitStream& bstr, unsigned& reference, unsigned huffmanNumber) { int code = bstr.read(2); if (code == 3) { reference = bstr.read(32); return true; } int bitlen = BitLength(huffmanNumber); assert(bitlen >= 2); reference = (code << (bitlen - 2)) | bstr.read(bitlen - 2); return true; }
void LenTable::Read(IBitStream &bitstr) { symidx2nodeidx.clear(); nodes.clear(); int count = bitstr.read(32); int bitsPerLen = bitstr.read(8); int idxBitSize = BitLength(count); symidx2nodeidx.resize(count); for (unsigned& nodeIdx : symidx2nodeidx) { nodeIdx = -1; // in case the root has a leaf as a child } nodes.resize(count - 1); int rootIdx = nodes.size() - 1; nodes.at(rootIdx) = {0,0,-1,-1}; nextNodePosition = 0; for (int i = 0; i < count; ++i) { int symidx = bitstr.read(idxBitSize); int len = bitstr.read(bitsPerLen); placeSymidx(symidx, rootIdx, len); } }
int LenTable::Decode(IBitStream &bitstr, unsigned &symIdx) const { const HuffmanNode* node = &nodes.back(); int len = 0; for (;;) { len++; int bit = bitstr.read(1); if (bit) { // right if (node->right < 0) { // leaf symIdx = -1 - node->right; return len; } node = &nodes.at(node->right - 1); } else { // left if (node->left < 0) { // leaf symIdx = -1 - node->left; return len; } node = &nodes.at(node->left - 1); } } // unreachable }