def decompress(data: bytes): rdr = BinaryReader(data) wtr = BinaryWriter() type = rdr.read_uint8() if type != 0x30: raise Exception("Tried to decompress commands that isn't RLE") ds = rdr.read_uint24() if ds == 0: rdr.read_uint32() while True: flag = rdr.read_uint8() if flag is None: break # we've hit the end compressed = (flag & 0x80) > 0 lenght = flag & 0x7f lenght += 3 if compressed else 1 if compressed: next = rdr.read_uint8() for i in range(lenght): wtr.write_uint8(next) else: wtr.write(rdr.read(lenght)) return wtr.data
def decompress(data: bytes) -> bytes: rdr = BinaryReader(data) wtr = BinaryWriter() compression_type = rdr.read_uint8() if compression_type == 0x24: blocksize = 4 elif compression_type == 0x28: blocksize = 8 else: raise Exception( "Tried to decompress something as huffman that isn't huffman") ds = rdr.read_uint24() if ds == 0: rdr.read_uint32() # Read the tree treesize = (rdr.read_uint8() + 1) * 2 tree_end = (rdr.c - 1) + treesize rootNode = HuffTreeNode.from_rdr(rdr, False, 5, tree_end) rdr.c = tree_end # Decompress with the tree bitsleft = 0 # amount of bits left to read from {commands} current_size = 0 currentNode = rootNode cashedbyte = -1 while current_size < ds: # Find next refrence to commands node while not currentNode.is_data: if bitsleft == 0: data = rdr.read_uint32() bitsleft = 32 bitsleft -= 1 nextIsOne = (data & (1 << bitsleft)) != 0 if nextIsOne: currentNode = currentNode.child1 else: currentNode = currentNode.child0 if blocksize == 8: current_size += 1 wtr.write_uint8(currentNode.data) elif blocksize == 4: if cashedbyte < 0: cashedbyte = currentNode.data else: cashedbyte |= currentNode.data << 4 wtr.write_uint8(cashedbyte) current_size += 1 cashedbyte = -1 currentNode = rootNode return wtr.data