Advertisement
Guest User

Untitled

a guest
Feb 18th, 2020
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.89 KB | None | 0 0
  1. """
  2. Joshua Stough
  3. DIP
  4.  
  5. LZW compression.
  6.  
  7. https://www2.cs.duke.edu/csed/curious/compression/lzw.html
  8. http://rosettacode.org/wiki/LZW_compression#Python
  9.  
  10. """
  11.  
  12. import matplotlib.pyplot as plt
  13. import numpy as np
  14.  
  15.  
  16. """
  17. LZWCompress: given a stream of uint8, outputs a
  18. generator outstream. parameter bits defines how
  19. many bits to encode each pattern with, or how
  20. big the dictionary gets.
  21. """
  22. class LZWCompress(object):
  23.     def __init__(self, instream, bits = 12):
  24.         self.instream = instream
  25.         self.bits = bits
  26.         self.table = {}
  27.  
  28.     def __iter__(self):
  29.         #myhash = lambda window: ' '.join(str(x) for x in window)
  30.         myhash = lambda window: ''.join(chr(x) if x != -1 else chr(256) for x in window)
  31. #         myhash = lambda window: ''.join(chr(x) for x in window)
  32.  
  33.         self.table = dict(zip([myhash([x]) for x in range(256)], range(256)))
  34.         self.table[chr(256)] = 256 # The 256th key-value of the table reserved for the negative value
  35.  
  36.         #siter = iter(self.instream)
  37.         curwindow = [] #s = empty
  38.  
  39.         for x in self.instream: #x is ch
  40. #             print(x)
  41.             if x < 0: # Split in two: negative sign and the positive number
  42.                 curwindow.append(-1)
  43.                 if myhash(curwindow) not in self.table: #if s+ch not in table
  44.                     yield self.table[myhash(curwindow[:-1])] #yield s
  45.  
  46.                     if len(self.table) < 2**self.bits: #if enough space in dict
  47.                         self.table[myhash(curwindow)] = len(self.table) #add s+ch
  48.  
  49.                     curwindow = [-1]  # set s = ch
  50.                 curwindow.append(-x) # Turn x to positive
  51.             else:
  52.                 curwindow.append(x) #s + ch
  53. #             curwindow.append(x)
  54. #             print(curwindow)
  55.             if myhash(curwindow) not in self.table: #if s+ch not in table
  56.                 yield self.table[myhash(curwindow[:-1])] #yield s
  57.  
  58.                 if len(self.table) < 2**self.bits: #if enough space in dict
  59.                     self.table[myhash(curwindow)] = len(self.table) #add s+ch
  60.  
  61.                 curwindow = [abs(x)]  # set s = ch
  62.  
  63.         yield self.table[myhash(curwindow)]
  64.  
  65. class LZWDecompress(object):
  66.     def __init__(self, compressedStream, bits = 12):
  67.         self.compressedStream = compressedStream
  68.         self.bits = bits
  69.         self.table = {}
  70.  
  71.     def __iter__(self):
  72.         #table is the other way around now.
  73.         self.table = dict(zip(range(256), [[x] for x in range(256)]))
  74.         self.table[256] = [256]
  75.  
  76.         itere = iter(self.compressedStream)
  77.         w = [next(itere)]
  78.         yield w[0]
  79.  
  80.         is_negative = False
  81.         for x in itere:
  82.             if x in self.table: #if it's already an entry
  83.                 entry = self.table[x]
  84.             elif x == len(self.table): #x isn't yet in the table.
  85.                 entry = w + [w[0]]
  86.             else:
  87.                 raise ValueError('saw compressed index %d, unknown' % x)
  88.  
  89.             for i in entry:
  90.                 if i == 256:
  91.                     is_negative = True
  92.                     continue
  93.                    
  94.                 if is_negative:
  95.                     is_negative = False
  96.                     yield -i
  97.                 else:
  98.                     yield i
  99. #                 yield i
  100.  
  101.             if len(self.table) < 2 ** self.bits:
  102.                 self.table[len(self.table)] = w + [entry[0]]
  103.  
  104.             w = entry
  105.  
  106.  
  107.  
  108. def loadHuffableImage(I):
  109.     if type(I) == str:
  110.         I = plt.imread(I)
  111.  
  112.     if (len(I.shape) > 2):
  113.         print("loadHuffableImage: input is multi-channel, using grayscale.")
  114.         Ig = 0.2989 * I[..., 0] + 0.5870 * I[..., 1] + 0.1140 * I[..., 2]
  115.         I = Ig
  116.  
  117.     if I.ravel().max() <= 1:
  118.         print('loadHuffableImage: Setting range to [0, 255]')
  119.         I = np.round(256*I)
  120.  
  121.     I[I > 255] = 255
  122.     I = I.copy().astype('uint8')
  123.  
  124.     return I
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement