RunLength decoder (Adobe version) implementation based on PDF Reference version 1.4 section 3.3.4: The RunLengthDecode filter decodes data that has been encoded in a simple byte-oriented format based on run length. The encoded data is a sequence of runs, where each r
(data)
| 9 | import sys |
| 10 | |
| 11 | def rldecode(data): |
| 12 | """ |
| 13 | RunLength decoder (Adobe version) implementation based on PDF Reference |
| 14 | version 1.4 section 3.3.4: |
| 15 | The RunLengthDecode filter decodes data that has been encoded in a |
| 16 | simple byte-oriented format based on run length. The encoded data |
| 17 | is a sequence of runs, where each run consists of a length byte |
| 18 | followed by 1 to 128 bytes of data. If the length byte is in the |
| 19 | range 0 to 127, the following length + 1 (1 to 128) bytes are |
| 20 | copied literally during decompression. If length is in the range |
| 21 | 129 to 255, the following single byte is to be copied 257 - length |
| 22 | (2 to 128) times during decompression. A length value of 128 |
| 23 | denotes EOD. |
| 24 | >>> s = "\x05123456\xfa7\x04abcde\x80junk" |
| 25 | >>> rldecode(s) |
| 26 | '1234567777777abcde' |
| 27 | """ |
| 28 | decoded = [] |
| 29 | i=0 |
| 30 | while i < len(data): |
| 31 | #print "data[%d]=:%d:" % (i,ord(data[i])) |
| 32 | length = ord(data[i]) |
| 33 | if length == 128: |
| 34 | break |
| 35 | if length >= 0 and length < 128: |
| 36 | run = data[i+1:(i+1)+(length+1)] |
| 37 | #print "length=%d, run=%s" % (length+1,run) |
| 38 | decoded.append(run) |
| 39 | i = (i+1) + (length+1) |
| 40 | if length > 128: |
| 41 | run = data[i+1]*(257-length) |
| 42 | #print "length=%d, run=%s" % (257-length,run) |
| 43 | decoded.append(run) |
| 44 | i = (i+1) + 1 |
| 45 | return ''.join(decoded) |
| 46 | |
| 47 | |
| 48 | if __name__ == '__main__': |