uint16 SmallHuffmanTree::decodeTree(uint32 prefix, int length) { if (!_bs.getBit()) { // Leaf _tree[_treeSize] = _bs.getBits8(); if (length <= 8) { for (int i = 0; i < 256; i += (1 << length)) { _prefixtree[prefix | i] = _treeSize; _prefixlength[prefix | i] = length; } } ++_treeSize; return 1; } uint16 t = _treeSize++; if (length == 8) { _prefixtree[prefix] = t; _prefixlength[prefix] = 8; } uint16 r1 = decodeTree(prefix, length + 1); _tree[t] = (SMK_NODE | r1); uint16 r2 = decodeTree(prefix | (1 << length), length + 1); return r1+r2+1; }
HUFF *decodeTree(BYTE **data) { HUFF *next; switch(decodeBit(data)) { case 0: next = calloc(sizeof(HUFF),1); next->ch = -1; next->children[0] = decodeTree(data); next->children[1] = decodeTree(data); break; case 1: next = &freqs[decodeByte(data)]; break; } return next; }
int extract(FILE *f, ArchFileInfo *info, char *fileName) { LOGGING_FUNC_START; int _error = 0; FILE *fOut = NULL; char *buf = malloc(BUF_SIZE*sizeof(char)); char *buf2Write = malloc(BUF_SIZE*sizeof(char)*8); size_t lenBits = 0; size_t readBytes = 0; size_t returnBytes = 0; size_t readedBytes = 0; size_t howManyBytesRead = 0; Tree *haffTree = NULL; if (NULL == (fOut = fopen(fileName, "wb"))) { IO(L"Couldnt open file `%s`", fileName); __forErrorFileName = fileName; LOGGING_FUNC_STOP; return FILE_OPEN_ERROR; } haffTree = decodeTree(info->haffTree,info->haffTreeSize); initDecoding(haffTree); for (readedBytes=0; readedBytes < info->dataSize;) { howManyBytesRead = min(BUF_SIZE, (info->dataSize - readedBytes)); _error = readNBytes(f, howManyBytesRead, buf, &readBytes); readedBytes += readBytes; if (_error) { IO(L"Error reading archive file"); LOGGING_FUNC_STOP; return ARCHIVE_ERROR; } lenBits = (howManyBytesRead < BUF_SIZE) ? readBytes*8 - info->endUnusedBits : readBytes*8; decode(buf,lenBits,buf2Write,&returnBytes); _error = writeNBytes(fOut, returnBytes, buf2Write); if (_error) { IO("Write error to `%s`", fileName); __forErrorFileName = fileName; return _error; } } fclose(fOut); free(haffTree); LOGGING_FUNC_STOP; return 0; }
uint32 BigHuffmanTree::decodeTree(uint32 prefix, int length) { uint32 bit = _bs.getBit(); if (!bit) { // Leaf uint32 lo = _loBytes->getCode(_bs); uint32 hi = _hiBytes->getCode(_bs); uint32 v = (hi << 8) | lo; _tree[_treeSize] = v; if (length <= 8) { for (int i = 0; i < 256; i += (1 << length)) { _prefixtree[prefix | i] = _treeSize; _prefixlength[prefix | i] = length; } } for (int i = 0; i < 3; ++i) { if (_markers[i] == v) { _last[i] = _treeSize; _tree[_treeSize] = 0; } } ++_treeSize; return 1; } uint32 t = _treeSize++; if (length == 8) { _prefixtree[prefix] = t; _prefixlength[prefix] = 8; } uint32 r1 = decodeTree(prefix, length + 1); _tree[t] = SMK_NODE | r1; uint32 r2 = decodeTree(prefix | (1 << length), length + 1); return r1+r2+1; }
SmallHuffmanTree::SmallHuffmanTree(BitStream &bs) : _treeSize(0), _bs(bs) { uint32 bit = _bs.getBit(); assert(bit); for (uint16 i = 0; i < 256; ++i) _prefixtree[i] = _prefixlength[i] = 0; decodeTree(0, 0); bit = _bs.getBit(); assert(!bit); }
void decode (char *name, BYTE *data) { if (strstr(name, ".hf") == name + strlen(name) - 3) { int val = 1; int len = *(int *) data; data += 4; HUFF *result = decodeTree(&data); name[strlen(name) - 3] = 0; strcat(name, ".hfd"); FILE *fil = fopen(name, "wb"); for (int i=0; i < len; i++) { fputc(decodeSymbol(&data, result), fil); } return; } printf("Not an hf file"); }
BigHuffmanTree::BigHuffmanTree(BitStream &bs, int allocSize) : _bs(bs) { uint32 bit = _bs.getBit(); if (!bit) { _tree = new uint32[1]; _tree[0] = 0; _last[0] = _last[1] = _last[2] = 0; return; } for (uint32 i = 0; i < 256; ++i) _prefixtree[i] = _prefixlength[i] = 0; _loBytes = new SmallHuffmanTree(_bs); _hiBytes = new SmallHuffmanTree(_bs); _markers[0] = _bs.getBits8(); _markers[0] |= (_bs.getBits8() << 8); _markers[1] = _bs.getBits8(); _markers[1] |= (_bs.getBits8() << 8); _markers[2] = _bs.getBits8(); _markers[2] |= (_bs.getBits8() << 8); _last[0] = _last[1] = _last[2] = 0xffffffff; _treeSize = 0; _tree = new uint32[allocSize / 4]; decodeTree(0, 0); bit = _bs.getBit(); assert(!bit); for (uint32 i = 0; i < 3; ++i) { if (_last[i] == 0xffffffff) { _last[i] = _treeSize; _tree[_treeSize++] = 0; } } delete _loBytes; delete _hiBytes; }
GadgetTreeReader::GadgetTreeReader(libember::util::OctetStream& input) { m_root = nullptr; auto& factory = GlowNodeFactory::getFactory(); auto reader = dom::DomReader(); auto node = reader.decodeTree(input, factory); if (node != nullptr) { auto const type = ber::Type::fromTag(node->typeTag()); if(type.isApplicationDefined()) { if (type.value() == GlowType::RootElementCollection) { auto collection = dynamic_cast<GlowRootElementCollection*>(node); if (collection != nullptr) { iterate(collection); } } } } }