Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- def _bits(d):
- """Iterates bytes-like object d, returning requested #bytes.
- Remember to initialize the iterator before use!
- Using next(_bits()) returns the next bit in the sequence.
- Use _bits.send() to request a given number of bits."""
- # Magic! Only if None will be 1!
- n = (yield 0) or 1
- o, c = 0, 0
- for i in d:
- while c >= n:
- m = o & ((1 << n) - 1)
- o >>= n
- c -= n
- n = (yield m) or 1
- i <<= c
- o |= i
- c += 8
- def _tbl(data):
- """Creates two blank tables, then calls _huffy() to fill it.
- Iterations return next value from the tree."""
- # I'll admit, this looks a little too much like magic.
- itr = _bits(data)
- next(itr)
- # The lower 0x100 entries of each table aren't used, but simplifies things.
- tbl = list(bytes(0x400))
- tbl.append(0x100)
- # Table is sent via pointer, so you see the changes here too.
- c = _huffy(itr, tbl)
- #yield c
- while True:
- v = c
- while v > 0xFF:
- v = tbl[v + (itr.send(1) << 9)]
- yield v
- def _huffy(itr, tbl):
- """Reentrant; fills table with entries from data stream.
- Returns current index."""
- if itr.send(1):
- c = tbl[-1]
- tbl[-1] += 1
- tbl[c] = _huffy(itr, tbl)
- tbl[c + 0x200] = _huffy(itr, tbl)
- return c
- return itr.send(8)
- def decode(data):
- # Read header.
- c = data[0] & 3
- dec_sz = int.from_bytes(data[1:4], 'big')
- if c == 0: # Copy
- return data[4:]
- elif c == 1: # Huffman
- c = _tbl(data[4:])
- out = bytearray()
- while len(out) < dec_sz:
- out.append(next(c))
- return out
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement