{-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE ExplicitNamespaces #-} {-# LANGUAGE RecordWildCards #-} module Codec.Compression.PPM.Coding (-- encode --, decode --, probability --, shiftCommonPrefix --, bitsToInteger ) where import Prelude hiding (subtract, lookup, last) import qualified Data.Map as Map import Data.Map (Map) import qualified Data.Maybe as M import Data.Bits import Control.Monad (join, liftM) import qualified Data.List as L import Data.Foldable (toList) import qualified Data.Sequence as Seq import Data.Sequence ((|>)) --import Codec.Compression.PPM.Trie (Trie(..), lookup) --import Codec.Compression.PPM.Utils (windows) import Data.Ratio ((%)) import Debug.Trace hiding (trace) -- first :: Word -- first = zeroBits `setBit` 0 -- last :: Word -- last = zeroBits `setBit` i -- where -- i = (finiteBitSize first) - 1 -- secondToLast :: Word -- secondToLast = zeroBits `setBit` i -- where -- i = (finiteBitSize first) - 2 -- shiftCommonPrefix :: State -> State -- shiftCommonPrefix (State {..}) = case lb == hb of -- True -> State { low=low `shiftL` 1, high=high `shiftL` 1 `setBit` 0, underflow=underflow, bits=lb:bits } -- False -> case lsb /= hsb of -- True -> State { low=low, high=high, underflow=underflow, bits=bits } -- False -> State { low=low, high=high, underflow=underflow, bits=bits } -- where -- i = (finiteBitSize low) - 1 -- lb = low `testBit` i -- hb = high `testBit` i -- lsb = low `testBit` (i - 1) -- hsb = high `testBit` (i - 1) -- --where -- -- go l' h' bs = case lb == hb of -- -- True -> go (shiftL l' 1 `clearBit` 0) (shiftL h' 1 `setBit` 0) (lb:bs) -- -- False -> (bs, l', h') -- bitsToInteger :: [Bool] -> Integer -- bitsToInteger = go 0 -- where -- go i [] = i -- go i (b:bs) = go ((if b == True then setBit else clearBit) (i `shift` 1) 0) bs -- data Symbol = Symbol { lowCount :: Integer -- , highCount :: Integer -- , scale :: Integer -- } deriving (Show) -- data State = State { low :: Word -- , high :: Word -- , underflow :: Int -- , bits :: [Bool] -- } deriving (Show) -- type Code = Trie (Maybe Char) (Integer, Integer) -- -- -- | Under a given trie and with the current range, return the updated range -- -- updateRange :: Code -> Word -> Word -> [Maybe Char] -> (Word, Word) -- -- updateRange tr cl ch i = shiftCommonPrefix l' h' -- -- where -- -- range = (ch - cl) + 1 -- -- Just (nl, nh) = case lookup i tr of -- -- Nothing -> error $ "No entry for: " ++ show es -- -- Just x -> value x -- -- Just (_, sc) = value tr -- -- l' = cl + ((range * nl) `div` sc) -- -- h' = cl + ((range * nh) `div` sc) - 1 -- trace :: (Show a) => a -> a -- trace a = a -- traceShow a a -- trace' :: (Show a) => String -> a -> a -- trace' s a = a --traceShow (s, a) a -- -- | -- encodeItem :: State -> Symbol -> State -- encodeItem (State{..}) (Symbol{..}) = shiftCommonPrefix $ State { low=fromIntegral (trace low'), high=fromIntegral (trace high'), underflow=underflow, bits=bits } -- where -- range = trace' "range: " $ (fromIntegral $ high - low :: Integer) + 1 -- l = fromIntegral low -- low' = l + (range * lowCount) `div` scale -- high' = l + (range * highCount) `div` scale - 1 -- --(shifted, low'', high'') = shiftCommonPrefix low' high' -- type Input = [Maybe Char] -- encode :: Code -> Int -> Input -> [Bool] -- encode code n xs = (reverse . bits) $ foldl encodeItem iState cs'' -- where -- iState = State zeroBits (complement zeroBits) 0 [] -- Just (_, top) = value code -- cs = [lookup i code | i <- windows n xs] -- cs' = [value tr | Just tr <- cs] -- cs'' = trace [Symbol l h top | Just (l, h) <- cs'] -- decode :: Trie e v -> Integer -> [e] -- decode tr i = go tr i [] -- where -- go tr' i' (Nothing:bs) = M.catMaybes $ reverse bs -- go tr' i' bs = go tr' i' (Nothing:bs) -- probability :: Trie e v -> [e] -> Double -- probability tr xs = 0.5