aydarbiktimirov

Huffman Coding/Decoding

Oct 17th, 2011
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Data.List (sortBy)
  2. import Data.Char (digitToInt, chr, ord)
  3.  
  4. probabilities "" = []
  5. probabilities (x:xs) = (x, length $ filter (== x) (x:xs)) : probabilities (filter (/= x) xs)
  6.  
  7. data HTree weight char = EmptyHTree | Leaf weight char | Branch weight (HTree weight char) (HTree weight char)
  8.     deriving (Show, Read)
  9.  
  10. weight (EmptyHTree) = 0
  11. weight (Leaf w _) = w
  12. weight (Branch w _ _) = w
  13.  
  14. compareHTree t1 t2 = compare (weight t1) (weight t2)
  15.  
  16. insert _ x [] = [x]
  17. insert predicate x (y:ys)
  18.     | predicate x y = (x:y:ys)
  19.     | otherwise = y:(insert predicate x ys)
  20.  
  21. _buildHTree [] = EmptyHTree
  22. _buildHTree [x] = x
  23. _buildHTree (x:y:xs) = _buildHTree $ insert (\x y -> (compareHTree x y) == LT) (Branch ((weight x) + (weight y)) x y) xs
  24.  
  25. buildHTree s = _buildHTree $ sortBy compareHTree $ map (\x -> Leaf (snd x) (fst x)) $ probabilities s
  26.  
  27. parseHTree prefix EmptyHTree = []
  28. parseHTree prefix (Leaf _ c) = [(prefix, c)]
  29. parseHTree prefix (Branch _ t1 t2) = (parseHTree (prefix ++ "0") t1) ++ (parseHTree (prefix ++ "1") t2)
  30.  
  31. buildHuffmanCodeTable s = parseHTree "" $ buildHTree s
  32.  
  33. huffmanCode s = bitsToString $ concat $ map (\x -> fst $ head $ filter (\y -> snd y == x) (buildHuffmanCodeTable s)) s
  34.     where
  35.         bitsToString s
  36.             | s == "" = ""
  37.             | length s < 8 = bitsToString $ take 8 (s ++ "00000000")
  38.             | otherwise = (byteToChar $ take 8 s) : bitsToString (drop 8 s)
  39.             where
  40.                 byteToChar s = chr $ foldl (\x y -> 2 * x + (digitToInt y)) 0 s
  41.  
  42. huffmanDecode probs s len = take len $ _huffmanDecode codeTable "" $ stringToBits s
  43.     where
  44.         codeTable = parseHTree "" $ _buildHTree $ sortBy compareHTree $ map (\x -> Leaf (snd x) (fst x)) $ probs
  45.  
  46.         _huffmanDecode codes prefix ""
  47.             | has prefix (map fst codes) = [snd $ head $ filter (\x -> fst x == prefix) codes]
  48.             | otherwise = ""
  49.         _huffmanDecode codes prefix s
  50.             | has prefix (map fst codes) = (snd $ head $ filter (\x -> fst x == prefix) codes) : _huffmanDecode codes "" s
  51.             | otherwise = _huffmanDecode codes (prefix ++ [head s]) (tail s)
  52.  
  53.         has x l = (length $ (filter (== x) l)) > 0
  54.  
  55.  
  56.         stringToBits "" = ""
  57.         stringToBits (x:xs) = (charToByte x) ++ stringToBits xs
  58.             where
  59.                 charToByte c = reverse $ take 8 $ ( _charToByte $ ord c) ++ "00000000"
  60.                     where
  61.                         _charToByte _c
  62.                             | _c == 0 = ""
  63.                             | mod _c 2 == 1 = '1' : (_charToByte (div _c 2))
  64.                             | otherwise = '0' : (_charToByte (div _c 2))
  65.  
  66.  
Advertisement
Add Comment
Please, Sign In to add comment