    {-# LANGUAGE Rank2Types #-}
    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE CPP #-}
    -- | This module implement helper functions to read & write data

    -- at bits level.

    module Codec.Picture.BitWriter( BoolReader
                                  , emptyBoolState
                                  , BoolState
                                  , byteAlignJpg
                                  , getNextBitsLSBFirst
                                  , getNextBitsMSBFirst
                                  , getNextBitJpg
                                  , getNextIntJpg
                                  , setDecodedString
                                  , setDecodedStringMSB
                                  , setDecodedStringJpg
                                  , runBoolReader

                                  , BoolWriteStateRef
                                  , newWriteStateRef
                                  , finalizeBoolWriter
                                  , finalizeBoolWriterGif
                                  , writeBits'
                                  , writeBitsGif

                                  , initBoolState
                                  , initBoolStateJpg
                                  , execBoolReader
                                  , runBoolReaderWith
                                  ) where

    #if !MIN_VERSION_base(4,8,0)
    import Control.Applicative( (<*>), (<$>) )
    #endif

    import Data.STRef
    import Control.Monad( when )
    import Control.Monad.ST( ST )
    import qualified Control.Monad.Trans.State.Strict as S
    import Data.Int ( Int32 )
    import Data.Word( Word8, Word32 )
    import Data.Bits( (.&.), (.|.), unsafeShiftR, unsafeShiftL )

    import Codec.Picture.VectorByteConversion( blitVector )
    import qualified Data.Vector.Storable.Mutable as M
    import qualified Data.Vector.Storable as VS
    import qualified Data.ByteString as B
    import qualified Data.ByteString.Lazy as L

    --------------------------------------------------

    ----            Reader

    --------------------------------------------------

    -- | Current bit index, current value, string

    data BoolState = BoolState {-# UNPACK #-} !Int
                               {-# UNPACK #-} !Word8
                               !B.ByteString

    emptyBoolState :: BoolState
    emptyBoolState :: BoolState
    emptyBoolState = Int -> Word8 -> ByteString -> BoolState
    BoolState (-1) 0 ByteString
    B.empty

    -- | Type used to read bits

    type BoolReader s a = S.StateT BoolState (ST s) a

    runBoolReader :: BoolReader s a -> ST s a
    runBoolReader :: BoolReader s a -> ST s a
    runBoolReader action :: BoolReader s a
    action = BoolReader s a -> BoolState -> ST s a
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    S.evalStateT BoolReader s a
    action (BoolState -> ST s a) -> BoolState -> ST s a
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState 0 0 ByteString
    B.empty

    runBoolReaderWith :: BoolState -> BoolReader s a -> ST s (a, BoolState)
    runBoolReaderWith :: BoolState -> BoolReader s a -> ST s (a, BoolState)
    runBoolReaderWith st :: BoolState
    st action :: BoolReader s a
    action = BoolReader s a -> BoolState -> ST s (a, BoolState)
    forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
    S.runStateT BoolReader s a
    action BoolState
    st

    execBoolReader :: BoolState -> BoolReader s a -> ST s BoolState
    execBoolReader :: BoolState -> BoolReader s a -> ST s BoolState
    execBoolReader st :: BoolState
    st reader :: BoolReader s a
    reader = BoolReader s a -> BoolState -> ST s BoolState
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
    S.execStateT BoolReader s a
    reader BoolState
    st

    initBoolState :: B.ByteString -> BoolState
    initBoolState :: ByteString -> BoolState
    initBoolState str :: ByteString
    str = case ByteString -> Maybe (Word8, ByteString)
    B.uncons ByteString
    str of
         Nothing -> Int -> Word8 -> ByteString -> BoolState
    BoolState 0 0 ByteString
    B.empty
         Just (v :: Word8
    v, rest :: ByteString
    rest) -> Int -> Word8 -> ByteString -> BoolState
    BoolState 0 Word8
    v ByteString
    rest

    initBoolStateJpg :: B.ByteString -> BoolState
    initBoolStateJpg :: ByteString -> BoolState
    initBoolStateJpg str :: ByteString
    str =
       case ByteString -> Maybe (Word8, ByteString)
    B.uncons ByteString
    str of
         Nothing -> Int -> Word8 -> ByteString -> BoolState
    BoolState 0 0 ByteString
    B.empty
         Just (0xFF, rest :: ByteString
    rest) -> case ByteString -> Maybe (Word8, ByteString)
    B.uncons ByteString
    rest of
                Nothing                  -> Int -> Word8 -> ByteString -> BoolState
    BoolState 7 0 ByteString
    B.empty
                Just (0x00, afterMarker :: ByteString
    afterMarker) -> Int -> Word8 -> ByteString -> BoolState
    BoolState 7 0xFF ByteString
    afterMarker
                Just (_   , afterMarker :: ByteString
    afterMarker) -> ByteString -> BoolState
    initBoolStateJpg ByteString
    afterMarker
         Just (v :: Word8
    v, rest :: ByteString
    rest) -> Int -> Word8 -> ByteString -> BoolState
    BoolState 7 Word8
    v ByteString
    rest

    -- | Bitify a list of things to decode.

    setDecodedString :: B.ByteString -> BoolReader s ()
    setDecodedString :: ByteString -> BoolReader s ()
    setDecodedString str :: ByteString
    str = case ByteString -> Maybe (Word8, ByteString)
    B.uncons ByteString
    str of
         Nothing        -> BoolState -> BoolReader s ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    S.put (BoolState -> BoolReader s ()) -> BoolState -> BoolReader s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState      0 0 ByteString
    B.empty
         Just (v :: Word8
    v, rest :: ByteString
    rest) -> BoolState -> BoolReader s ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    S.put (BoolState -> BoolReader s ()) -> BoolState -> BoolReader s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState      0 Word8
    v    ByteString
    rest

    -- | Drop all bit until the bit of indice 0, usefull to parse restart

    -- marker, as they are byte aligned, but Huffman might not.

    byteAlignJpg :: BoolReader s ()
    byteAlignJpg :: BoolReader s ()
    byteAlignJpg = do
      BoolState idx :: Int
    idx _ chain :: ByteString
    chain <- StateT BoolState (ST s) BoolState
    forall (m :: * -> *) s. Monad m => StateT s m s
    S.get
      Bool -> BoolReader s () -> BoolReader s ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Int
    idx Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= 7) (ByteString -> BoolReader s ()
    forall s. ByteString -> BoolReader s ()
    setDecodedStringJpg ByteString
    chain)

    getNextBitJpg :: BoolReader s Bool
    {-# INLINE getNextBitJpg #-}
    getNextBitJpg :: BoolReader s Bool
    getNextBitJpg = do
        BoolState idx :: Int
    idx v :: Word8
    v chain :: ByteString
    chain <- StateT BoolState (ST s) BoolState
    forall (m :: * -> *) s. Monad m => StateT s m s
    S.get
        let val :: Bool
    val = (Word8
    v Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. (1 Word8 -> Int -> Word8
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    idx)) Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    /= 0
        if Int
    idx Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0
          then ByteString -> BoolReader s ()
    forall s. ByteString -> BoolReader s ()
    setDecodedStringJpg ByteString
    chain
          else BoolState -> BoolReader s ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    S.put (BoolState -> BoolReader s ()) -> BoolState -> BoolReader s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState (Int
    idx Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1) Word8
    v ByteString
    chain
        Bool -> BoolReader s Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    val

    getNextIntJpg :: Int -> BoolReader s Int32
    {-# INLINE getNextIntJpg #-}
    getNextIntJpg :: Int -> BoolReader s Int32
    getNextIntJpg = Int32 -> Int -> BoolReader s Int32
    forall a s.
    (Bits a, Num a) =>
    a -> Int -> StateT BoolState (ST s) a
    go 0 where
      go :: a -> Int -> StateT BoolState (ST s) a
    go !a
    acc !Int
    0 = a -> StateT BoolState (ST s) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a
    acc
      go !a
    acc !Int
    n = do
        BoolState idx :: Int
    idx v :: Word8
    v chain :: ByteString
    chain <- StateT BoolState (ST s) BoolState
    forall (m :: * -> *) s. Monad m => StateT s m s
    S.get
        let !leftBits :: Int
    leftBits = 1 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    idx
        if Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    leftBits then do
          ByteString -> BoolReader s ()
    forall s. ByteString -> BoolReader s ()
    setDecodedStringJpg ByteString
    chain
          let !remaining :: Int
    remaining = Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    leftBits
              !mask :: a
    mask = (1 a -> Int -> a
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    leftBits) a -> a -> a
    forall a. Num a => a -> a -> a
    - 1
              !finalV :: a
    finalV = Word8 -> a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word8
    v a -> a -> a
    forall a. Bits a => a -> a -> a
    .&. a
    mask
              !theseBits :: a
    theseBits = a
    finalV a -> Int -> a
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    remaining
          a -> Int -> StateT BoolState (ST s) a
    go (a
    acc a -> a -> a
    forall a. Bits a => a -> a -> a
    .|. a
    theseBits) Int
    remaining
        else do
          let !remaining :: Int
    remaining = Int
    leftBits Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    n
              !mask :: a
    mask = (1 a -> Int -> a
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    n) a -> a -> a
    forall a. Num a => a -> a -> a
    - 1
              !finalV :: a
    finalV = Word8 -> a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word8
    v a -> Int -> a
    forall a. Bits a => a -> Int -> a
    `unsafeShiftR` Int
    remaining
          BoolState -> BoolReader s ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    S.put (BoolState -> BoolReader s ()) -> BoolState -> BoolReader s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState (Int -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    remaining Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1) Word8
    v ByteString
    chain
          a -> StateT BoolState (ST s) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a -> StateT BoolState (ST s) a) -> a -> StateT BoolState (ST s) a
    forall a b. (a -> b) -> a -> b
    $ (a
    finalV a -> a -> a
    forall a. Bits a => a -> a -> a
    .&. a
    mask) a -> a -> a
    forall a. Bits a => a -> a -> a
    .|. a
    acc

    setDecodedStringMSB :: B.ByteString -> BoolReader s ()
    setDecodedStringMSB :: ByteString -> BoolReader s ()
    setDecodedStringMSB str :: ByteString
    str = case ByteString -> Maybe (Word8, ByteString)
    B.uncons ByteString
    str of
      Nothing        -> BoolState -> BoolReader s ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    S.put (BoolState -> BoolReader s ()) -> BoolState -> BoolReader s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState      8 0 ByteString
    B.empty
      Just (v :: Word8
    v, rest :: ByteString
    rest) -> BoolState -> BoolReader s ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    S.put (BoolState -> BoolReader s ()) -> BoolState -> BoolReader s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState      8 Word8
    v    ByteString
    rest

    {-# INLINE getNextBitsMSBFirst #-}
    getNextBitsMSBFirst :: Int -> BoolReader s Word32
    getNextBitsMSBFirst :: Int -> BoolReader s Word32
    getNextBitsMSBFirst requested :: Int
    requested = Word32 -> Int -> BoolReader s Word32
    forall s. Word32 -> Int -> BoolReader s Word32
    go 0 Int
    requested where
      go :: Word32 -> Int -> BoolReader s Word32
      go :: Word32 -> Int -> BoolReader s Word32
    go !Word32
    acc !Int
    0 = Word32 -> BoolReader s Word32
    forall (m :: * -> *) a. Monad m => a -> m a
    return Word32
    acc
      go !Word32
    acc !Int
    n = do
        BoolState idx :: Int
    idx v :: Word8
    v chain :: ByteString
    chain <- StateT BoolState (ST s) BoolState
    forall (m :: * -> *) s. Monad m => StateT s m s
    S.get
        let !leftBits :: Int
    leftBits = Int -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    idx
        if Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    leftBits then do
          ByteString -> BoolReader s ()
    forall s. ByteString -> BoolReader s ()
    setDecodedStringMSB ByteString
    chain
          let !theseBits :: Word32
    theseBits = Word8 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word8
    v Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    leftBits)
          Word32 -> Int -> BoolReader s Word32
    forall s. Word32 -> Int -> BoolReader s Word32
    go (Word32
    acc Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .|. Word32
    theseBits) (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    leftBits)
        else do
          let !remaining :: Int
    remaining = Int
    leftBits Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    n
              !mask :: Word8
    mask = (1 Word8 -> Int -> Word8
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    remaining) Word8 -> Word8 -> Word8
    forall a. Num a => a -> a -> a
    - 1
          BoolState -> BoolReader s ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    S.put (BoolState -> BoolReader s ()) -> BoolState -> BoolReader s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState (Int -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    remaining) (Word8
    v Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. Word8
    mask) ByteString
    chain
          Word32 -> BoolReader s Word32
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Word32 -> BoolReader s Word32) -> Word32 -> BoolReader s Word32
    forall a b. (a -> b) -> a -> b
    $ (Word8 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word8
    v Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `unsafeShiftR` Int
    remaining) Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .|. Word32
    acc

    {-# INLINE getNextBitsLSBFirst #-}
    getNextBitsLSBFirst :: Int -> BoolReader s Word32
    getNextBitsLSBFirst :: Int -> BoolReader s Word32
    getNextBitsLSBFirst count :: Int
    count = Word32 -> Int -> BoolReader s Word32
    forall a s.
    (Bits a, Num a) =>
    a -> Int -> StateT BoolState (ST s) a
    aux 0 Int
    count
      where aux :: t -> Int -> StateT BoolState (ST s) t
    aux acc :: t
    acc 0 = t -> StateT BoolState (ST s) t
    forall (m :: * -> *) a. Monad m => a -> m a
    return t
    acc
            aux acc :: t
    acc n :: Int
    n = do
                Bool
    bit <- BoolReader s Bool
    forall s. BoolReader s Bool
    getNextBit
                let nextVal :: t
    nextVal | Bool
    bit = t
    acc t -> t -> t
    forall a. Bits a => a -> a -> a
    .|. (1 t -> Int -> t
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` (Int
    count Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    n))
                            | Bool
    otherwise = t
    acc
                t -> Int -> StateT BoolState (ST s) t
    aux t
    nextVal (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1)

    {-# INLINE getNextBit #-}
    getNextBit :: BoolReader s Bool
    getNextBit :: BoolReader s Bool
    getNextBit = do
        BoolState idx :: Int
    idx v :: Word8
    v chain :: ByteString
    chain <- StateT BoolState (ST s) BoolState
    forall (m :: * -> *) s. Monad m => StateT s m s
    S.get
        let val :: Bool
    val = (Word8
    v Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. (1 Word8 -> Int -> Word8
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    idx)) Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    /= 0
        if Int
    idx Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 7
          then ByteString -> BoolReader s ()
    forall s. ByteString -> BoolReader s ()
    setDecodedString ByteString
    chain
          else BoolState -> BoolReader s ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    S.put (BoolState -> BoolReader s ()) -> BoolState -> BoolReader s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState (Int
    idx Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + 1) Word8
    v ByteString
    chain
        Bool -> BoolReader s Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    val

    -- | Bitify a list of things to decode. Handle Jpeg escape

    -- code (0xFF 0x00), thus should be only used in JPEG decoding.

    setDecodedStringJpg :: B.ByteString -> BoolReader s ()
    setDecodedStringJpg :: ByteString -> BoolReader s ()
    setDecodedStringJpg str :: ByteString
    str = case ByteString -> Maybe (Word8, ByteString)
    B.uncons ByteString
    str of
         Nothing        -> BoolState -> BoolReader s ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    S.put (BoolState -> BoolReader s ()) -> BoolState -> BoolReader s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState 7 0 ByteString
    B.empty
         Just (0xFF, rest :: ByteString
    rest) -> case ByteString -> Maybe (Word8, ByteString)
    B.uncons ByteString
    rest of
                Nothing                  -> BoolState -> BoolReader s ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    S.put (BoolState -> BoolReader s ()) -> BoolState -> BoolReader s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState 7 0 ByteString
    B.empty
                Just (0x00, afterMarker :: ByteString
    afterMarker) -> -- trace "00" $

                    BoolState -> BoolReader s ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    S.put (BoolState -> BoolReader s ()) -> BoolState -> BoolReader s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState 7 0xFF ByteString
    afterMarker
                Just (_   , afterMarker :: ByteString
    afterMarker) -> ByteString -> BoolReader s ()
    forall s. ByteString -> BoolReader s ()
    setDecodedStringJpg ByteString
    afterMarker
         Just (v :: Word8
    v, rest :: ByteString
    rest) ->
            BoolState -> BoolReader s ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    S.put (BoolState -> BoolReader s ()) -> BoolState -> BoolReader s ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> ByteString -> BoolState
    BoolState 7 Word8
    v ByteString
    rest

    --------------------------------------------------

    ----            Writer

    --------------------------------------------------

    defaultBufferSize :: Int
    defaultBufferSize :: Int
    defaultBufferSize = 256 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * 1024

    data BoolWriteStateRef s = BoolWriteStateRef
            { BoolWriteStateRef s -> STRef s (MVector s Word8)
    bwsCurrBuffer   :: STRef s (M.MVector s Word8)
            , BoolWriteStateRef s -> STRef s [ByteString]
    bwsBufferList   :: STRef s [B.ByteString]
            , BoolWriteStateRef s -> STRef s Int
    bwsWrittenWords :: STRef s Int
            , BoolWriteStateRef s -> STRef s Word8
    bwsBitAcc       :: STRef s Word8
            , BoolWriteStateRef s -> STRef s Int
    bwsBitReaded    :: STRef s Int
            }

    newWriteStateRef :: ST s (BoolWriteStateRef s)
    newWriteStateRef :: ST s (BoolWriteStateRef s)
    newWriteStateRef = do
        MVector s Word8
    origMv <- Int -> ST s (MVector (PrimState (ST s)) Word8)
    forall (m :: * -> *) a.
    (PrimMonad m, Storable a) =>
    Int -> m (MVector (PrimState m) a)
    M.new Int
    defaultBufferSize
        STRef s (MVector s Word8)
    -> STRef s [ByteString]
    -> STRef s Int
    -> STRef s Word8
    -> STRef s Int
    -> BoolWriteStateRef s
    forall s.
    STRef s (MVector s Word8)
    -> STRef s [ByteString]
    -> STRef s Int
    -> STRef s Word8
    -> STRef s Int
    -> BoolWriteStateRef s
    BoolWriteStateRef (STRef s (MVector s Word8)
     -> STRef s [ByteString]
     -> STRef s Int
     -> STRef s Word8
     -> STRef s Int
     -> BoolWriteStateRef s)
    -> ST s (STRef s (MVector s Word8))
    -> ST
         s
         (STRef s [ByteString]
          -> STRef s Int
          -> STRef s Word8
          -> STRef s Int
          -> BoolWriteStateRef s)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> MVector s Word8 -> ST s (STRef s (MVector s Word8))
    forall a s. a -> ST s (STRef s a)
    newSTRef MVector s Word8
    origMv
                          ST
      s
      (STRef s [ByteString]
       -> STRef s Int
       -> STRef s Word8
       -> STRef s Int
       -> BoolWriteStateRef s)
    -> ST s (STRef s [ByteString])
    -> ST
         s
         (STRef s Int
          -> STRef s Word8 -> STRef s Int -> BoolWriteStateRef s)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> [ByteString] -> ST s (STRef s [ByteString])
    forall a s. a -> ST s (STRef s a)
    newSTRef []
                          ST
      s
      (STRef s Int
       -> STRef s Word8 -> STRef s Int -> BoolWriteStateRef s)
    -> ST s (STRef s Int)
    -> ST s (STRef s Word8 -> STRef s Int -> BoolWriteStateRef s)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Int -> ST s (STRef s Int)
    forall a s. a -> ST s (STRef s a)
    newSTRef 0
                          ST s (STRef s Word8 -> STRef s Int -> BoolWriteStateRef s)
    -> ST s (STRef s Word8)
    -> ST s (STRef s Int -> BoolWriteStateRef s)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Word8 -> ST s (STRef s Word8)
    forall a s. a -> ST s (STRef s a)
    newSTRef 0
                          ST s (STRef s Int -> BoolWriteStateRef s)
    -> ST s (STRef s Int) -> ST s (BoolWriteStateRef s)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Int -> ST s (STRef s Int)
    forall a s. a -> ST s (STRef s a)
    newSTRef 0

    finalizeBoolWriter :: BoolWriteStateRef s -> ST s L.ByteString
    finalizeBoolWriter :: BoolWriteStateRef s -> ST s ByteString
    finalizeBoolWriter st :: BoolWriteStateRef s
    st = do
        BoolWriteStateRef s -> ST s ()
    forall s. BoolWriteStateRef s -> ST s ()
    flushLeftBits' BoolWriteStateRef s
    st
        BoolWriteStateRef s -> ST s ()
    forall s. BoolWriteStateRef s -> ST s ()
    forceBufferFlushing' BoolWriteStateRef s
    st
        [ByteString] -> ByteString
    L.fromChunks ([ByteString] -> ByteString)
    -> ST s [ByteString] -> ST s ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> STRef s [ByteString] -> ST s [ByteString]
    forall s a. STRef s a -> ST s a
    readSTRef (BoolWriteStateRef s -> STRef s [ByteString]
    forall s. BoolWriteStateRef s -> STRef s [ByteString]
    bwsBufferList BoolWriteStateRef s
    st)

    forceBufferFlushing' :: BoolWriteStateRef s -> ST s ()
    forceBufferFlushing' :: BoolWriteStateRef s -> ST s ()
    forceBufferFlushing' (BoolWriteStateRef { bwsCurrBuffer :: forall s. BoolWriteStateRef s -> STRef s (MVector s Word8)
    bwsCurrBuffer = STRef s (MVector s Word8)
    vecRef
                                            , bwsWrittenWords :: forall s. BoolWriteStateRef s -> STRef s Int
    bwsWrittenWords = STRef s Int
    countRef
                                            , bwsBufferList :: forall s. BoolWriteStateRef s -> STRef s [ByteString]
    bwsBufferList = STRef s [ByteString]
    lstRef
                                            }) = do
        MVector s Word8
    vec <- STRef s (MVector s Word8) -> ST s (MVector s Word8)
    forall s a. STRef s a -> ST s a
    readSTRef STRef s (MVector s Word8)
    vecRef
        Int
    count <- STRef s Int -> ST s Int
    forall s a. STRef s a -> ST s a
    readSTRef STRef s Int
    countRef
        [ByteString]
    lst <- STRef s [ByteString] -> ST s [ByteString]
    forall s a. STRef s a -> ST s a
    readSTRef STRef s [ByteString]
    lstRef

        MVector s Word8
    nmv <- Int -> ST s (MVector (PrimState (ST s)) Word8)
    forall (m :: * -> *) a.
    (PrimMonad m, Storable a) =>
    Int -> m (MVector (PrimState m) a)
    M.new Int
    defaultBufferSize
        ByteString
    str <- MVector s Word8 -> Int -> ST s ByteString
    forall s. MVector s Word8 -> Int -> ST s ByteString
    byteStringFromVector MVector s Word8
    vec Int
    count

        STRef s (MVector s Word8) -> MVector s Word8 -> ST s ()
    forall s a. STRef s a -> a -> ST s ()
    writeSTRef STRef s (MVector s Word8)
    vecRef MVector s Word8
    nmv
        STRef s [ByteString] -> [ByteString] -> ST s ()
    forall s a. STRef s a -> a -> ST s ()
    writeSTRef STRef s [ByteString]
    lstRef ([ByteString] -> ST s ()) -> [ByteString] -> ST s ()
    forall a b. (a -> b) -> a -> b
    $ [ByteString]
    lst [ByteString] -> [ByteString] -> [ByteString]
    forall a. [a] -> [a] -> [a]
    ++ [ByteString
    str]
        STRef s Int -> Int -> ST s ()
    forall s a. STRef s a -> a -> ST s ()
    writeSTRef STRef s Int
    countRef 0

    flushCurrentBuffer' :: BoolWriteStateRef s -> ST s ()
    flushCurrentBuffer' :: BoolWriteStateRef s -> ST s ()
    flushCurrentBuffer' st :: BoolWriteStateRef s
    st = do
        Int
    count <- STRef s Int -> ST s Int
    forall s a. STRef s a -> ST s a
    readSTRef (STRef s Int -> ST s Int) -> STRef s Int -> ST s Int
    forall a b. (a -> b) -> a -> b
    $ BoolWriteStateRef s -> STRef s Int
    forall s. BoolWriteStateRef s -> STRef s Int
    bwsWrittenWords BoolWriteStateRef s
    st
        Bool -> ST s () -> ST s ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Int
    count Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    defaultBufferSize)
             (BoolWriteStateRef s -> ST s ()
    forall s. BoolWriteStateRef s -> ST s ()
    forceBufferFlushing' BoolWriteStateRef s
    st)

    byteStringFromVector :: M.MVector s Word8 -> Int -> ST s B.ByteString
    byteStringFromVector :: MVector s Word8 -> Int -> ST s ByteString
    byteStringFromVector vec :: MVector s Word8
    vec size :: Int
    size = do
        Vector Word8
    frozen <- MVector (PrimState (ST s)) Word8 -> ST s (Vector Word8)
    forall a (m :: * -> *).
    (Storable a, PrimMonad m) =>
    MVector (PrimState m) a -> m (Vector a)
    VS.unsafeFreeze MVector s Word8
    MVector (PrimState (ST s)) Word8
    vec
        ByteString -> ST s ByteString
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ByteString -> ST s ByteString) -> ByteString -> ST s ByteString
    forall a b. (a -> b) -> a -> b
    $ Vector Word8 -> Int -> Int -> ByteString
    blitVector Vector Word8
    frozen 0 Int
    size

    setBitCount' :: BoolWriteStateRef s -> Word8 -> Int -> ST s ()
    {-# INLINE setBitCount' #-}
    setBitCount' :: BoolWriteStateRef s -> Word8 -> Int -> ST s ()
    setBitCount' st :: BoolWriteStateRef s
    st acc :: Word8
    acc count :: Int
    count = do
        STRef s Word8 -> Word8 -> ST s ()
    forall s a. STRef s a -> a -> ST s ()
    writeSTRef (BoolWriteStateRef s -> STRef s Word8
    forall s. BoolWriteStateRef s -> STRef s Word8
    bwsBitAcc BoolWriteStateRef s
    st) Word8
    acc
        STRef s Int -> Int -> ST s ()
    forall s a. STRef s a -> a -> ST s ()
    writeSTRef (BoolWriteStateRef s -> STRef s Int
    forall s. BoolWriteStateRef s -> STRef s Int
    bwsBitReaded BoolWriteStateRef s
    st) Int
    count

    resetBitCount' :: BoolWriteStateRef s -> ST s ()
    {-# INLINE resetBitCount' #-}
    resetBitCount' :: BoolWriteStateRef s -> ST s ()
    resetBitCount' st :: BoolWriteStateRef s
    st = BoolWriteStateRef s -> Word8 -> Int -> ST s ()
    forall s. BoolWriteStateRef s -> Word8 -> Int -> ST s ()
    setBitCount' BoolWriteStateRef s
    st 0 0

    pushByte' :: BoolWriteStateRef s -> Word8 -> ST s ()
    {-# INLINE pushByte' #-}
    pushByte' :: BoolWriteStateRef s -> Word8 -> ST s ()
    pushByte' st :: BoolWriteStateRef s
    st v :: Word8
    v = do
        BoolWriteStateRef s -> ST s ()
    forall s. BoolWriteStateRef s -> ST s ()
    flushCurrentBuffer' BoolWriteStateRef s
    st
        Int
    idx <- STRef s Int -> ST s Int
    forall s a. STRef s a -> ST s a
    readSTRef (BoolWriteStateRef s -> STRef s Int
    forall s. BoolWriteStateRef s -> STRef s Int
    bwsWrittenWords BoolWriteStateRef s
    st)
        MVector s Word8
    vec <- STRef s (MVector s Word8) -> ST s (MVector s Word8)
    forall s a. STRef s a -> ST s a
    readSTRef (BoolWriteStateRef s -> STRef s (MVector s Word8)
    forall s. BoolWriteStateRef s -> STRef s (MVector s Word8)
    bwsCurrBuffer BoolWriteStateRef s
    st)
        MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
    forall (m :: * -> *) a.
    (PrimMonad m, Storable a) =>
    MVector (PrimState m) a -> Int -> a -> m ()
    M.write MVector s Word8
    MVector (PrimState (ST s)) Word8
    vec Int
    idx Word8
    v
        STRef s Int -> Int -> ST s ()
    forall s a. STRef s a -> a -> ST s ()
    writeSTRef (BoolWriteStateRef s -> STRef s Int
    forall s. BoolWriteStateRef s -> STRef s Int
    bwsWrittenWords BoolWriteStateRef s
    st) (Int -> ST s ()) -> Int -> ST s ()
    forall a b. (a -> b) -> a -> b
    $ Int
    idx Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + 1

    flushLeftBits' :: BoolWriteStateRef s -> ST s ()
    flushLeftBits' :: BoolWriteStateRef s -> ST s ()
    flushLeftBits' st :: BoolWriteStateRef s
    st = do
        Int
    currCount <- STRef s Int -> ST s Int
    forall s a. STRef s a -> ST s a
    readSTRef (STRef s Int -> ST s Int) -> STRef s Int -> ST s Int
    forall a b. (a -> b) -> a -> b
    $ BoolWriteStateRef s -> STRef s Int
    forall s. BoolWriteStateRef s -> STRef s Int
    bwsBitReaded BoolWriteStateRef s
    st
        Bool -> ST s () -> ST s ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Int
    currCount Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 0) (ST s () -> ST s ()) -> ST s () -> ST s ()
    forall a b. (a -> b) -> a -> b
    $ do
          Word8
    currWord <- STRef s Word8 -> ST s Word8
    forall s a. STRef s a -> ST s a
    readSTRef (STRef s Word8 -> ST s Word8) -> STRef s Word8 -> ST s Word8
    forall a b. (a -> b) -> a -> b
    $ BoolWriteStateRef s -> STRef s Word8
    forall s. BoolWriteStateRef s -> STRef s Word8
    bwsBitAcc BoolWriteStateRef s
    st
          BoolWriteStateRef s -> Word8 -> ST s ()
    forall s. BoolWriteStateRef s -> Word8 -> ST s ()
    pushByte' BoolWriteStateRef s
    st (Word8 -> ST s ()) -> Word8 -> ST s ()
    forall a b. (a -> b) -> a -> b
    $ Word8
    currWord Word8 -> Int -> Word8
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` (8 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    currCount)

    -- | Append some data bits to a Put monad.

    writeBits' :: BoolWriteStateRef s
               -> Word32     -- ^ The real data to be stored. Actual data should be in the LSB

               -> Int        -- ^ Number of bit to write from 1 to 32

               -> ST s ()
    {-# INLINE writeBits' #-}
    writeBits' :: BoolWriteStateRef s -> Word32 -> Int -> ST s ()
    writeBits' st :: BoolWriteStateRef s
    st d :: Word32
    d c :: Int
    c = do
        Word8
    currWord <- STRef s Word8 -> ST s Word8
    forall s a. STRef s a -> ST s a
    readSTRef (STRef s Word8 -> ST s Word8) -> STRef s Word8 -> ST s Word8
    forall a b. (a -> b) -> a -> b
    $ BoolWriteStateRef s -> STRef s Word8
    forall s. BoolWriteStateRef s -> STRef s Word8
    bwsBitAcc BoolWriteStateRef s
    st
        Int
    currCount <- STRef s Int -> ST s Int
    forall s a. STRef s a -> ST s a
    readSTRef (STRef s Int -> ST s Int) -> STRef s Int -> ST s Int
    forall a b. (a -> b) -> a -> b
    $  BoolWriteStateRef s -> STRef s Int
    forall s. BoolWriteStateRef s -> STRef s Int
    bwsBitReaded BoolWriteStateRef s
    st
        Word32 -> Int -> Word8 -> Int -> ST s ()
    serialize Word32
    d Int
    c Word8
    currWord Int
    currCount
      where dumpByte :: Word8 -> ST s ()
    dumpByte 0xFF = BoolWriteStateRef s -> Word8 -> ST s ()
    forall s. BoolWriteStateRef s -> Word8 -> ST s ()
    pushByte' BoolWriteStateRef s
    st 0xFF ST s () -> ST s () -> ST s ()
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BoolWriteStateRef s -> Word8 -> ST s ()
    forall s. BoolWriteStateRef s -> Word8 -> ST s ()
    pushByte' BoolWriteStateRef s
    st 0x00
            dumpByte    i :: Word8
    i = BoolWriteStateRef s -> Word8 -> ST s ()
    forall s. BoolWriteStateRef s -> Word8 -> ST s ()
    pushByte' BoolWriteStateRef s
    st Word8
    i

            serialize :: Word32 -> Int -> Word8 -> Int -> ST s ()
    serialize bitData :: Word32
    bitData bitCount :: Int
    bitCount currentWord :: Word8
    currentWord count :: Int
    count
                | Int
    bitCount Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    count Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 8 = do
                         BoolWriteStateRef s -> ST s ()
    forall s. BoolWriteStateRef s -> ST s ()
    resetBitCount' BoolWriteStateRef s
    st
                         Word8 -> ST s ()
    dumpByte (Word8 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word8 -> Word8) -> Word8 -> Word8
    forall a b. (a -> b) -> a -> b
    $ (Word8
    currentWord Word8 -> Int -> Word8
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    bitCount) Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .|.
                                                    Word32 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word32
    cleanData)

                | Int
    bitCount Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    count Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 8 =
                    let newVal :: Word8
    newVal = Word8
    currentWord Word8 -> Int -> Word8
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    bitCount
                    in BoolWriteStateRef s -> Word8 -> Int -> ST s ()
    forall s. BoolWriteStateRef s -> Word8 -> Int -> ST s ()
    setBitCount' BoolWriteStateRef s
    st (Word8
    newVal Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .|. Word32 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word32
    cleanData) (Int -> ST s ()) -> Int -> ST s ()
    forall a b. (a -> b) -> a -> b
    $ Int
    count Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    bitCount

                | Bool
    otherwise =
                    let leftBitCount :: Int
    leftBitCount = 8 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    count :: Int
                        highPart :: Word32
    highPart = Word32
    cleanData Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `unsafeShiftR` (Int
    bitCount Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    leftBitCount) :: Word32
                        prevPart :: Word32
    prevPart = Word8 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word8
    currentWord Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    leftBitCount :: Word32

                        nextMask :: Word32
    nextMask = (1 Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` (Int
    bitCount Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    leftBitCount)) Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    - 1 :: Word32
                        newData :: Word32
    newData = Word32
    cleanData Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .&. Word32
    nextMask :: Word32
                        newCount :: Int
    newCount = Int
    bitCount Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    leftBitCount :: Int

                        toWrite :: Word8
    toWrite = Word32 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word32 -> Word8) -> Word32 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Word32
    prevPart Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .|. Word32
    highPart :: Word8
                    in Word8 -> ST s ()
    dumpByte Word8
    toWrite ST s () -> ST s () -> ST s ()
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Word32 -> Int -> Word8 -> Int -> ST s ()
    serialize Word32
    newData Int
    newCount 0 0

                  where cleanMask :: Word32
    cleanMask = (1 Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    bitCount) Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    - 1 :: Word32
                        cleanData :: Word32
    cleanData = Word32
    bitData Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .&. Word32
    cleanMask     :: Word32

    -- | Append some data bits to a Put monad.

    writeBitsGif :: BoolWriteStateRef s
                 -> Word32     -- ^ The real data to be stored. Actual data should be in the LSB

                 -> Int        -- ^ Number of bit to write from 1 to 32

                 -> ST s ()
    {-# INLINE writeBitsGif #-}
    writeBitsGif :: BoolWriteStateRef s -> Word32 -> Int -> ST s ()
    writeBitsGif st :: BoolWriteStateRef s
    st d :: Word32
    d c :: Int
    c = do
        Word8
    currWord <- STRef s Word8 -> ST s Word8
    forall s a. STRef s a -> ST s a
    readSTRef (STRef s Word8 -> ST s Word8) -> STRef s Word8 -> ST s Word8
    forall a b. (a -> b) -> a -> b
    $ BoolWriteStateRef s -> STRef s Word8
    forall s. BoolWriteStateRef s -> STRef s Word8
    bwsBitAcc BoolWriteStateRef s
    st
        Int
    currCount <- STRef s Int -> ST s Int
    forall s a. STRef s a -> ST s a
    readSTRef (STRef s Int -> ST s Int) -> STRef s Int -> ST s Int
    forall a b. (a -> b) -> a -> b
    $  BoolWriteStateRef s -> STRef s Int
    forall s. BoolWriteStateRef s -> STRef s Int
    bwsBitReaded BoolWriteStateRef s
    st
        Word32 -> Int -> Word8 -> Int -> ST s ()
    serialize Word32
    d Int
    c Word8
    currWord Int
    currCount
      where dumpByte :: Word8 -> ST s ()
    dumpByte = BoolWriteStateRef s -> Word8 -> ST s ()
    forall s. BoolWriteStateRef s -> Word8 -> ST s ()
    pushByte' BoolWriteStateRef s
    st

            serialize :: Word32 -> Int -> Word8 -> Int -> ST s ()
    serialize bitData :: Word32
    bitData bitCount :: Int
    bitCount currentWord :: Word8
    currentWord count :: Int
    count
                | Int
    bitCount Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    count Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 8 = do
                         BoolWriteStateRef s -> ST s ()
    forall s. BoolWriteStateRef s -> ST s ()
    resetBitCount' BoolWriteStateRef s
    st
                         Word8 -> ST s ()
    dumpByte (Word8 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word8 -> Word8) -> Word8 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Word8
    currentWord  Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .|.
                                                    (Word32 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word32
    cleanData Word8 -> Int -> Word8
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    count))

                | Int
    bitCount Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    count Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 8 =
                    let newVal :: Word8
    newVal = Word32 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word32
    cleanData Word8 -> Int -> Word8
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    count
                    in BoolWriteStateRef s -> Word8 -> Int -> ST s ()
    forall s. BoolWriteStateRef s -> Word8 -> Int -> ST s ()
    setBitCount' BoolWriteStateRef s
    st (Word8
    newVal Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .|. Word8
    currentWord) (Int -> ST s ()) -> Int -> ST s ()
    forall a b. (a -> b) -> a -> b
    $ Int
    count Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    bitCount

                | Bool
    otherwise =
                    let leftBitCount :: Int
    leftBitCount = 8 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    count :: Int
                        newData :: Word32
    newData = Word32
    cleanData Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `unsafeShiftR` Int
    leftBitCount :: Word32
                        newCount :: Int
    newCount = Int
    bitCount Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    leftBitCount :: Int
                        toWrite :: Word8
    toWrite = Word32 -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word32 -> Word8) -> Word32 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Word8 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word8
    currentWord
                                                Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .|. (Word32
    cleanData Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    count) :: Word8
                    in Word8 -> ST s ()
    dumpByte Word8
    toWrite ST s () -> ST s () -> ST s ()
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Word32 -> Int -> Word8 -> Int -> ST s ()
    serialize Word32
    newData Int
    newCount 0 0

                  where cleanMask :: Word32
    cleanMask = (1 Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    bitCount) Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    - 1 :: Word32
                        cleanData :: Word32
    cleanData = Word32
    bitData Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .&. Word32
    cleanMask     :: Word32

    finalizeBoolWriterGif :: BoolWriteStateRef s -> ST s L.ByteString
    finalizeBoolWriterGif :: BoolWriteStateRef s -> ST s ByteString
    finalizeBoolWriterGif st :: BoolWriteStateRef s
    st = do
        BoolWriteStateRef s -> ST s ()
    forall s. BoolWriteStateRef s -> ST s ()
    flushLeftBitsGif BoolWriteStateRef s
    st
        BoolWriteStateRef s -> ST s ()
    forall s. BoolWriteStateRef s -> ST s ()
    forceBufferFlushing' BoolWriteStateRef s
    st
        [ByteString] -> ByteString
    L.fromChunks ([ByteString] -> ByteString)
    -> ST s [ByteString] -> ST s ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> STRef s [ByteString] -> ST s [ByteString]
    forall s a. STRef s a -> ST s a
    readSTRef (BoolWriteStateRef s -> STRef s [ByteString]
    forall s. BoolWriteStateRef s -> STRef s [ByteString]
    bwsBufferList BoolWriteStateRef s
    st)

    flushLeftBitsGif :: BoolWriteStateRef s -> ST s ()
    flushLeftBitsGif :: BoolWriteStateRef s -> ST s ()
    flushLeftBitsGif st :: BoolWriteStateRef s
    st = do
        Int
    currCount <- STRef s Int -> ST s Int
    forall s a. STRef s a -> ST s a
    readSTRef (STRef s Int -> ST s Int) -> STRef s Int -> ST s Int
    forall a b. (a -> b) -> a -> b
    $ BoolWriteStateRef s -> STRef s Int
    forall s. BoolWriteStateRef s -> STRef s Int
    bwsBitReaded BoolWriteStateRef s
    st
        Bool -> ST s () -> ST s ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Int
    currCount Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 0) (ST s () -> ST s ()) -> ST s () -> ST s ()
    forall a b. (a -> b) -> a -> b
    $ do
          Word8
    currWord <- STRef s Word8 -> ST s Word8
    forall s a. STRef s a -> ST s a
    readSTRef (STRef s Word8 -> ST s Word8) -> STRef s Word8 -> ST s Word8
    forall a b. (a -> b) -> a -> b
    $ BoolWriteStateRef s -> STRef s Word8
    forall s. BoolWriteStateRef s -> STRef s Word8
    bwsBitAcc BoolWriteStateRef s
    st
          BoolWriteStateRef s -> Word8 -> ST s ()
    forall s. BoolWriteStateRef s -> Word8 -> ST s ()
    pushByte' BoolWriteStateRef s
    st Word8
    currWord

    {-# ANN module "HLint: ignore Reduce duplication" #-}