View difference between Paste ID: 2yHPQjCQ and gZPTRADY
SHOW: | | - or go back to the newest paste.
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-
    print(data[:50])
29+
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]*265]*(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 = 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
            #// But we must update the size and code bits for the decoder's sake
58
            if (next_code & (next_code - 1)) == 0:  #// Is a power of 2
59
                code_size += 1
60
                # TODO: clean this up # Should be way nicer to calc.. to tired TODO: 
61
                root.extend( [ [ [None]*255 ] * ((1 << code_size) - (1 << (code_size-1))) ] )
62
                #print("increase code size to", self.codeBits)
63
            next_code += 1
64
        else:
65
            writer.write_bits(clear_code, code_size)                
66
            code_size = code_bits +1
67
            next_code = eoi_code +1
68
            root = [[None]*265]*(1 << code_size)
69
            pass
70
                
71
    writer.write_bits(eoi_code, code_size)
72
    writer.finish()
73
    return buf.getvalue()