Advertisement
Guest User

Untitled

a guest
Feb 4th, 2016
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.07 KB | None | 0 0
  1. from PIL import Image
  2. import math
  3. import numpy
  4. import struct
  5. import sys
  6. import PIL
  7.  
  8. def calc_DCT(N):
  9.     DCT = numpy.zeros([N, N])
  10.     for i in range(N):
  11.         for j in range(N):
  12.             if i == 0:
  13.                 DCT[i, j] = 1 / math.sqrt(N)
  14.             else:
  15.                 DCT[i, j] = math.sqrt(2 / N) * math.cos((2 * j + 1) * i * math.pi / (2 * N))
  16.     return numpy.matrix(DCT)
  17.  
  18. def calc_Q(N, q):
  19.     Q = numpy.zeros([N, N])
  20.     for i in range(N):
  21.         for j in range(N):
  22.             Q[i, j] = 1 + ((1 + i + j) * q)
  23.     return numpy.matrix(Q)
  24.  
  25. def expand(A, m ,n):
  26.     col = numpy.ones((A.shape[0], n - A.shape[1])) * 255
  27.     A = numpy.append(A, col, 1)
  28.     row = numpy.ones((m - A.shape[0], A.shape[1])) * 255
  29.     A = numpy.append(A, row, 0)
  30.     return A
  31.  
  32. def quantization(A, Q):
  33.     B = numpy.zeros([A.shape[0], A.shape[1]])
  34.     for i in range(0, A.shape[0]):
  35.         for j in range(0, A.shape[1]):
  36.             B[i, j] = A[i, j] / Q[i, j]
  37.     return numpy.matrix(B)
  38.  
  39. def InverseQuantization(A, Q):
  40.     B = numpy.zeros([A.shape[0], A.shape[1]])
  41.     for i in range(0, A.shape[0]):
  42.         for j in range(0, A.shape[1]):
  43.             B[i, j] = A[i, j] * Q[i, j]
  44.     return numpy.matrix(B)
  45.  
  46. def ZigZag(A):
  47.     def move(i, j):
  48.         if j < (A.shape[0] - 1):
  49.             return max(0, i-1), j+1
  50.         else:
  51.             return i+1, j
  52.     S = list()
  53.     x, y = 0, 0
  54.     for n in range(A.shape[0] * A.shape[0]):
  55.         S.append(A[y, x])
  56.         if (x + y) & 1:
  57.             x, y = move(x, y)
  58.         else:
  59.             y, x = move(y, x)
  60.     return S
  61.  
  62. def ZigZagInverse(S, size):
  63.     def move(i, j):
  64.         if j < (A.shape[0] - 1):
  65.             return max(0, i-1), j+1
  66.         else:
  67.             return i+1, j
  68.     A = numpy.zeros([size, size])
  69.     x, y = 0, 0
  70.     for k in range(size * size):
  71.         A[y, x] = S.pop(0)
  72.         if (x + y) & 1:
  73.             x, y = move(x, y)
  74.         else:
  75.             y, x = move(y, x)
  76.     return numpy.matrix(A)
  77.  
  78. def DCT_Image(A):
  79.     S = list()
  80.     for i in range(0, A.shape[0], 8):
  81.         for j in range(0, A.shape[1], 8):
  82.             IMG = in_data[i:i + 8, j:j + 8]
  83.             IMG = IMG - 128
  84.             RES = DCT * IMG * DCT_T
  85.             RES = quantization(RES, Q)
  86.             RES = numpy.int8(RES)
  87.             S = S + ZigZag(RES)
  88.     return S
  89.  
  90. def InverseDCT(S, m, n, Q):
  91.     img = numpy.zeros([0, n])
  92.     for i in range(0, m, 8):
  93.         row = numpy.zeros([8, 0])
  94.         for j in range(0, n, 8):
  95.             A = ZigZagInverse(S, 8)
  96.             A = InverseQuantization(A, Q)
  97.             A = DCT_T * A * DCT
  98.             A = A + 128
  99.             A = numpy.uint8(A)
  100.             row = numpy.append(row, A, 1)
  101.         img = numpy.append(img, row, 0)
  102.     return numpy.matrix(img)
  103.  
  104. def RLE_Coder(S):
  105.     RES = list()
  106.     counter = 0
  107.     INPUT = list(S)
  108.     n = 0
  109.     while INPUT:
  110.         byte = INPUT.pop(0)
  111.         if byte == 0:
  112.             n = 1
  113.             while True:
  114.                 if len(INPUT) == 0:
  115.                     RES.append(0)
  116.                     RES.append(n)
  117.                     break
  118.                 byte = INPUT.pop(0)
  119.                 if byte == 0:
  120.                     n = n + 1
  121.                     if n == 128:
  122.                         RES.append(0)
  123.                         RES.append(n - 1)
  124.                         n = 1
  125.                 else:
  126.                     RES.append(0)
  127.                     RES.append(n)
  128.                     RES.append(byte)
  129.                     break
  130.         else:
  131.             RES.append(byte)
  132.                    
  133.     return RES
  134.  
  135. def RLE_Decoder(S):
  136.     RES = list()
  137.     INPUT = list(S)
  138.     while INPUT:
  139.         byte = INPUT.pop(0)
  140.         if byte == 0:
  141.             n = INPUT.pop(0)
  142.             for i in range(n):
  143.                 RES.append(0)
  144.         else:
  145.             RES.append(byte)
  146.     return RES
  147.  
  148. def Save(S, imgWidth, imgHeight, filename):
  149.     file = open(filename, "wb")
  150.     file.write(struct.pack("I", imgWidth))
  151.     file.write(struct.pack("I", imgHeight))
  152.     for byte in S:
  153.         file.write(struct.pack("b", byte))
  154.     file.close()
  155.     return
  156.  
  157. def Open(filename):
  158.     file = open(filename, "rb")
  159.     imgWidth = struct.unpack("I", file.read(4))[0]
  160.     imgHeight = struct.unpack("I", file.read(4))[0]
  161.     S = numpy.fromfile(file, dtype = numpy.int8).tolist()
  162.     file.close()
  163.     return S, imgWidth, imgHeight
  164.  
  165. DCT = calc_DCT(8)
  166. DCT_T = numpy.transpose(DCT)
  167. Q = calc_Q(8, 5)
  168. Q[0, 0] = 8
  169.  
  170. print("Compress: comp inputFilename outputFilename")
  171. print("Decompress: decomp inputFilename outputFilename")
  172. print("Exit: q")
  173.  
  174. while True:
  175.     text = input("> ").split()
  176.     if (len(text) < 1):
  177.         print("wrong command")
  178.     else:
  179.         if len(text) >= 1:
  180.             command = text.pop(0)
  181.             if command == "q":
  182.                 sys.exit(0)
  183.         if len(text) != 2:
  184.             print("wrong command")
  185.         else:
  186.             inputFilename = text.pop(0)
  187.             outputFilename = text.pop(0)
  188.             if command == "comp":
  189.                 img = Image.open(inputFilename).convert('L')
  190.                 imgWidth = img.size[0]
  191.                 imgHeight = img.size[1]
  192.                 in_data = numpy.matrix(expand(numpy.asarray(img, dtype = numpy.uint8),
  193.                      imgHeight if (imgHeight % 8 == 0) else imgHeight + 8 - (imgHeight % 8),
  194.                      imgWidth if (imgWidth % 8 == 0) else imgWidth + 8 - (imgWidth % 8)))
  195.                 serial_out = DCT_Image(in_data)
  196.                 print("DCT max = ", max(serial_out))
  197.                 print("DCT min = ",min(serial_out))
  198.                 RLE_Out = RLE_Coder(serial_out)
  199.                 Save(RLE_Out, imgWidth, imgHeight, outputFilename,)
  200.             else:
  201.                 if command == "decomp":
  202.                     S, imgWidth, imgHeight = Open(inputFilename)
  203.                     out_data = RLE_Decoder(S)
  204.                     out_data = InverseDCT(out_data, imgHeight, imgWidth, Q)
  205.                     PIL.Image.fromarray(numpy.uint8(out_data)).save(outputFilename)
  206.                 else:
  207.                     print("wrong command")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement