Huffman Encoded File Format
Python
This are python function to decode HE3 compressed format used in MyList.DcLst file. To use this function:
he3_decoder('path/to/MyList.DcLst','path/to/Uncompressed.MyList.DcLst')
To further increase speed by up to 10x, run psyco module:
try:
import psyco
psyco.profile()
except ImportError:
pass
Decompression routine:
""" HE3 compression decoder by Dody Suria Wijaya <[email protected] Converted originally from he3.c by Eric Prevoteau <[email protected]> """ import struct, array, os def he3_decoder(path_from, path_to): data = array.array('B') data.fromfile(file(path_from,'rb'), os.path.getsize(path_from)) if not data[0:4].tostring().startswith('HE3\r'): raise Exception, 'Invalid HE3 header format. If this a HE3 file?' nb_output = struct.unpack('<L',data[5:9].tostring())[0] nb_couple = struct.unpack('<H',data[9:11].tostring())[0] max_len = 0 #max size of encoded pattern ttl_len = 0 #total size of all encoded patterns for pos in xrange(nb_couple): v = data[12 + pos*2] if v > max_len: max_len = v ttl_len += v decode_array = array.array('B', chr(0) * (1 << (max_len+1))) offset_pattern = 8 * (11+nb_couple*2) #position of the pattern block, it is just after the list of couples offset_encoded = offset_pattern + ((ttl_len+7) & ~7) #the encoded data are just after the pattern block (rounded to upper full byte) for pos in xrange(nb_couple): v_len = data[12 + pos*2] #the number of bit required res = 0 for i in xrange(v_len): res = (res << 1) | ((data[offset_pattern / 8] >> (offset_pattern & 7)) & 1) offset_pattern += 1 decode_array[(1 << v_len) + res] = data[11 + pos*2] # the character output = array.array('B', chr(0)*nb_output) for i in xrange(nb_output): cur_val = (data[offset_encoded/8] >> (offset_encoded & 7)) & 1 # get one bit offset_encoded += 1 nb_bit_val = 1 while decode_array[(1 << nb_bit_val) + cur_val] == 0: cur_val = (cur_val << 1) | ((data[offset_encoded/8] >> (offset_encoded & 7)) & 1) offset_encoded += 1 nb_bit_val += 1 output[i] = decode_array[(1 << nb_bit_val) + cur_val] output.tofile(file(path_to,'wb'))
