Advertisement
Guest User

Untitled

a guest
Jul 30th, 2015
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class BitWriter():
  2.     def __init__(self, consumer):
  3.         self.consumer = consumer
  4.         self.bit_buffer = 0
  5.         self.bit_buffer_len = 0
  6.        
  7.     def write_bits(self, value, bits):
  8.         # TODO catch invalid parameter
  9.         self.bit_buffer |= value << self.bit_buffer_len
  10.         self.bit_buffer_len += bits
  11.         while self.bit_buffer_len >= 8:
  12.             self.consumer.write(chr(self.bit_buffer & 0xff))
  13.             self.bit_buffer >>= 8
  14.             self.bit_buffer_len -= 8
  15.            
  16.     def finish(self):
  17.         if self.bit_buffer_len > 0:
  18.             self.consumer.write(chr(self.bit_buffer & 0xff))
  19.  
  20. def lzw_encode_default(data, code_bits):
  21.     """
  22.    @data: bytes (in py3) or something iterable with ints <= 255
  23.    @code_bits: the minimum_lzw_size (size of code in bits at start = code_bits +1)
  24.    data should contain the frames pixel index data.
  25.    The result is a string (or byte in py3).
  26.    TODO: replace StringIO with BytesIo
  27.    """
  28.     MAX_DICT_SIZE = 4096
  29.     buf = StringIO()
  30.     writer = BitWriter(buf)
  31.    
  32.     if code_bits < 2 or code_bits > 8:
  33.         raise Exception("Invalid code size");
  34.    
  35.     code_size = code_bits +1
  36.     clear_code = 1 << code_bits
  37.     eoi_code = clear_code +1
  38.     next_code = eoi_code +1
  39.     # We could use lists or arrays or something more memory friendly here i guess ?
  40.     # Also we don't really need to recreate all the lists. Zeroing all fields should be enough ?
  41.     root = [[None]*256]*(1 << code_size)
  42.     writer.write_bits(clear_code, code_size)
  43.    
  44.     i = 1
  45.     last_index = data[0]
  46.     while i < len(data) -1:
  47.         # Loop till we find an unknown sequence
  48.         while i < len(data) -1 and not root[last_index][data[i]] is None:
  49.             last_index = root[last_index][data[i]]
  50.             i += 1
  51.  
  52.         writer.write_bits(last_index, code_size)
  53.         root[last_index][data[i]] = next_code
  54.        
  55.         # Add new dictionary entry
  56.         if next_code < MAX_DICT_SIZE:
  57.             if (next_code & (next_code - 1)) == 0:  #// Is a power of 2
  58.                 code_size += 1
  59.                 # TODO: clean this up # Should be way nicer to calc.. to tired TODO:
  60.                 root.extend( [ [None]*255 ] * ((1 << code_size) - (1 << (code_size-1))) )
  61.                 #print("increase code size to", self.codeBits)
  62.             next_code += 1
  63.         else:
  64.             writer.write_bits(clear_code, code_size)                
  65.             code_size = code_bits +1
  66.             next_code = eoi_code +1
  67.             root = [[None]*265]*(1 << code_size)
  68.             pass
  69.                
  70.     writer.write_bits(eoi_code, code_size)
  71.     writer.finish()
  72.     return buf.getvalue()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement