    {-# LANGUAGE CPP #-}
    module Codec.Picture.InternalHelper ( runGet
                                        , runGetStrict
                                        , decode
                                        , getRemainingBytes
                                        , getRemainingLazyBytes ) where

    import qualified Data.ByteString as B
    import qualified Data.ByteString.Lazy as L
    import Data.Binary( Binary( get ) )
    import Data.Binary.Get( Get
                          , getRemainingLazyByteString
                          )
    import qualified Data.Binary.Get as G

    #if MIN_VERSION_binary(0,6,4)
    #else
    import Control.Applicative( (<$>) )
    import qualified Control.Exception as E
    -- I feel so dirty. :(

    import System.IO.Unsafe( unsafePerformIO )
    #endif

    decode :: (Binary a) => B.ByteString -> Either String a
    decode :: ByteString -> Either String a
    decode = Get a -> ByteString -> Either String a
    forall a. Get a -> ByteString -> Either String a
    runGetStrict Get a
    forall t. Binary t => Get t
    get

    runGet :: Get a -> L.ByteString -> Either String a
    #if MIN_VERSION_binary(0,6,4)
    runGet :: Get a -> ByteString -> Either String a
    runGet act :: Get a
    act = Either (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
    -> Either String a
    forall a b a a b b. Either (a, b, a) (a, b, b) -> Either a b
    unpack (Either
       (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
     -> Either String a)
    -> (ByteString
        -> Either
             (ByteString, ByteOffset, String) (ByteString, ByteOffset, a))
    -> ByteString
    -> Either String a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Get a
    -> ByteString
    -> Either
         (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
    forall a.
    Get a
    -> ByteString
    -> Either
         (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
    G.runGetOrFail Get a
    act
        where unpack :: Either (a, b, a) (a, b, b) -> Either a b
    unpack (Left (_, _, str :: a
    str)) = a -> Either a b
    forall a b. a -> Either a b
    Left a
    str
              unpack (Right (_, _, element :: b
    element)) = b -> Either a b
    forall a b. b -> Either a b
    Right b
    element
    #else
    runGet act str = unsafePerformIO $ E.catch
        (Right <$> E.evaluate (G.runGet act str))
        (\msg -> return . Left $ show (msg :: E.SomeException))
    #endif

    runGetStrict :: Get a -> B.ByteString -> Either String a
    runGetStrict :: Get a -> ByteString -> Either String a
    runGetStrict act :: Get a
    act buffer :: ByteString
    buffer = Get a -> ByteString -> Either String a
    forall a. Get a -> ByteString -> Either String a
    runGet Get a
    act (ByteString -> Either String a) -> ByteString -> Either String a
    forall a b. (a -> b) -> a -> b
    $ [ByteString] -> ByteString
    L.fromChunks [ByteString
    buffer]

    getRemainingBytes :: Get B.ByteString
    getRemainingBytes :: Get ByteString
    getRemainingBytes = do
        ByteString
    rest <- Get ByteString
    getRemainingLazyByteString
        ByteString -> Get ByteString
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ByteString -> Get ByteString) -> ByteString -> Get ByteString
    forall a b. (a -> b) -> a -> b
    $ case ByteString -> [ByteString]
    L.toChunks ByteString
    rest of
            [] -> ByteString
    B.empty
            [a :: ByteString
    a] -> ByteString
    a
            lst :: [ByteString]
    lst -> [ByteString] -> ByteString
    B.concat [ByteString]
    lst

    getRemainingLazyBytes :: Get L.ByteString
    getRemainingLazyBytes :: Get ByteString
    getRemainingLazyBytes = Get ByteString
    getRemainingLazyByteString