def extract(self, output_file): """ Restore the compressed data """ # create a dictionary with key => string matches st = dict() for i in xrange(self.radix): st[i] = chr(i) i += 1 # i = 256 - reserved as an EOF signal br = BitReader(self.file) codeword = int(br.readbits(self.codeword_width)) val = st[codeword] while True: # write unpacked value output_file.write(val) codeword = int(br.readbits(self.codeword_width)) if codeword == self.radix: # EOF break if i == codeword: # special case hack (when we don't have the needed key in st, but we have just met in input) new_value = val + val[0] else: new_value = st[codeword] if i < self.codeword_limit: i += 1 st[i] = val + new_value[0] val = new_value
def compress(tree, uncompressed, compressed): '''First write the given tree to the stream 'compressed' using the write_tree function. Then use the same tree to encode the data from the input stream 'uncompressed' and write it to 'compressed'. If there are any partially-written bytes remaining at the end, write 0 bits to form a complete byte. Args: tree: A Huffman tree. uncompressed: A file stream from which you can read the input. compressed: A file stream that will receive the tree description and the coded input data. ''' table = huffman.make_encoding_table(tree) uncomp = BitReader(uncompressed) comp = BitWriter(compressed) write_tree(tree, comp) while True: try: uncomp_btye = uncomp.readbits(8) print(uncomp_btye) comp_path = table[uncomp_btye] for bit in comp_path: if bit == False: comp.writebit(0) elif bit == True: comp.writebit(1) print(comp_path) except EOFError: comp_path = table[None] print("EOF") for bit in comp_path: comp.writebit(bit) print(comp_path) break comp.flush()
def extract(self, output_file): """ Restore the compressed data """ br = BitReader(self.file) root = self._read_trie(br) # number of bytes to write length = int(br.readbits(8)) bw = BitWriter(output_file) # decode using the Huffman trie for i in xrange(length): node = root while not node.is_leaf: bit = br.readbit() if bit: node = node.right else: node = node.left # write the character to output bw.writebits(node.char, 8)