{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE CPP #-}
module Codec.Picture.Jpg.Internal.Progressive
    ( JpgUnpackerParameter( .. )
    , progressiveUnpack
    ) where

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

import Control.Monad( when, unless, forM_ )
import Control.Monad.ST( ST )
import Control.Monad.Trans( lift )
import Data.Bits( (.&.), (.|.), unsafeShiftL )
import Data.Int( Int16, Int32 )
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
import qualified Data.Vector as V
import qualified Data.Vector.Storable as VS
import Data.Vector( (!) )
import qualified Data.Vector.Mutable as M
import qualified Data.Vector.Storable.Mutable as MS

import Codec.Picture.Types
import Codec.Picture.BitWriter
import Codec.Picture.Jpg.Internal.Common
import Codec.Picture.Jpg.Internal.Types
import Codec.Picture.Jpg.Internal.DefaultTable

createMcuLineIndices :: JpgComponent -> Int -> Int -> V.Vector (VS.Vector Int)
createMcuLineIndices :: JpgComponent -> Int -> Int -> Vector (Vector Int)
createMcuLineIndices JpgComponent
param Int
imgWidth Int
mcuWidth =
 forall a. [a] -> Vector a
V.fromList forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [a] -> Vector a
VS.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [[Int]
indexSolo, [Int]
indexMulti]
  where compW :: Int
compW = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ JpgComponent -> Word8
horizontalSamplingFactor JpgComponent
param
        compH :: Int
compH = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ JpgComponent -> Word8
verticalSamplingFactor JpgComponent
param
        imageBlockSize :: Int
imageBlockSize = Int -> Int
toBlockSize Int
imgWidth

        -- if the displayed MCU block is only displayed in half (like with

        -- width 500 then we loose one macroblock of the MCU at the end of

        -- the line. Previous implementation which naively used full mcu

        -- was wrong. Only taking into account visible macroblocks

        indexSolo :: [Int]
indexSolo = [Int
base forall a. Num a => a -> a -> a
+ Int
x
            | Int
y <- [Int
0 .. Int
compH forall a. Num a => a -> a -> a
- Int
1]
            , let base :: Int
base = Int
y forall a. Num a => a -> a -> a
* Int
mcuWidth forall a. Num a => a -> a -> a
* Int
compW
            , Int
x <- [Int
0 .. Int
imageBlockSize forall a. Num a => a -> a -> a
- Int
1]]

        indexMulti :: [Int]
indexMulti =
            [(Int
mcu forall a. Num a => a -> a -> a
+ Int
y forall a. Num a => a -> a -> a
* Int
mcuWidth) forall a. Num a => a -> a -> a
* Int
compW forall a. Num a => a -> a -> a
+ Int
x
                | Int
mcu <- [Int
0 .. Int
mcuWidth forall a. Num a => a -> a -> a
- Int
1]
                , Int
y <- [Int
0 .. Int
compH forall a. Num a => a -> a -> a
- Int
1]
                , Int
x <- [Int
0 .. Int
compW forall a. Num a => a -> a -> a
- Int
1] ]

decodeFirstDC :: JpgUnpackerParameter
              -> MS.STVector s Int16
              -> MutableMacroBlock s Int16
              -> Int32
              -> BoolReader s Int32
decodeFirstDC :: forall s.
JpgUnpackerParameter
-> STVector s Int16
-> STVector s Int16
-> Int32
-> BoolReader s Int32
decodeFirstDC JpgUnpackerParameter
params STVector s Int16
dcCoeffs STVector s Int16
block Int32
eobrun = StateT BoolState (ST s) ()
unpack forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Applicative f => a -> f a
pure Int32
eobrun
  where unpack :: StateT BoolState (ST s) ()
unpack = do
          (Int16
dcDeltaCoefficient) <- forall s. HuffmanPackedTree -> BoolReader s Int16
dcCoefficientDecode forall a b. (a -> b) -> a -> b
$ JpgUnpackerParameter -> HuffmanPackedTree
dcHuffmanTree JpgUnpackerParameter
params
          Int16
previousDc <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ STVector s Int16
dcCoeffs forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`MS.unsafeRead` JpgUnpackerParameter -> Int
componentIndex JpgUnpackerParameter
params
          let neoDcCoefficient :: Int16
neoDcCoefficient = Int16
previousDc forall a. Num a => a -> a -> a
+ Int16
dcDeltaCoefficient
              approxLow :: Int
approxLow = forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ JpgUnpackerParameter -> (Int, Int)
successiveApprox JpgUnpackerParameter
params
              scaledDc :: Int16
scaledDc = Int16
neoDcCoefficient forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
approxLow
          forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ (STVector s Int16
block forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`MS.unsafeWrite` Int
0) Int16
scaledDc 
          forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ (STVector s Int16
dcCoeffs forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`MS.unsafeWrite` JpgUnpackerParameter -> Int
componentIndex JpgUnpackerParameter
params) Int16
neoDcCoefficient

decodeRefineDc :: JpgUnpackerParameter
               -> a
               -> MutableMacroBlock s Int16
               -> Int32
               -> BoolReader s Int32
decodeRefineDc :: forall a s.
JpgUnpackerParameter
-> a -> MutableMacroBlock s Int16 -> Int32 -> BoolReader s Int32
decodeRefineDc JpgUnpackerParameter
params a
_ MutableMacroBlock s Int16
block Int32
eobrun = StateT BoolState (ST s) ()
unpack forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Applicative f => a -> f a
pure Int32
eobrun
  where approxLow :: Int
approxLow = forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ JpgUnpackerParameter -> (Int, Int)
successiveApprox JpgUnpackerParameter
params
        plusOne :: Int16
plusOne = Int16
1 forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
approxLow
        unpack :: StateT BoolState (ST s) ()
unpack = do
            Bool
bit <- forall s. BoolReader s Bool
getNextBitJpg
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
bit forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ do
                Int16
v <- MutableMacroBlock s Int16
block forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`MS.unsafeRead` Int
0
                (MutableMacroBlock s Int16
block forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`MS.unsafeWrite` Int
0) forall a b. (a -> b) -> a -> b
$ Int16
v forall a. Bits a => a -> a -> a
.|. Int16
plusOne

decodeFirstAc :: JpgUnpackerParameter
              -> a
              -> MutableMacroBlock s Int16
              -> Int32
              -> BoolReader s Int32
decodeFirstAc :: forall a s.
JpgUnpackerParameter
-> a -> MutableMacroBlock s Int16 -> Int32 -> BoolReader s Int32
decodeFirstAc JpgUnpackerParameter
_params a
_ MutableMacroBlock s Int16
_block Int32
eobrun | Int32
eobrun forall a. Ord a => a -> a -> Bool
> Int32
0 = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Int32
eobrun forall a. Num a => a -> a -> a
- Int32
1
decodeFirstAc JpgUnpackerParameter
params a
_ MutableMacroBlock s Int16
block Int32
_ = Int -> StateT BoolState (ST s) Int32
unpack Int
startIndex
  where (Int
startIndex, Int
maxIndex) = JpgUnpackerParameter -> (Int, Int)
coefficientRange JpgUnpackerParameter
params
        (Int
low, Int
_) = JpgUnpackerParameter -> (Int, Int)
successiveApprox JpgUnpackerParameter
params
        unpack :: Int -> StateT BoolState (ST s) Int32
unpack Int
n | Int
n forall a. Ord a => a -> a -> Bool
> Int
maxIndex = forall (f :: * -> *) a. Applicative f => a -> f a
pure Int32
0
        unpack Int
n = do
            (Int, Int)
rrrrssss <- forall s. HuffmanPackedTree -> BoolReader s (Int, Int)
decodeRrrrSsss forall a b. (a -> b) -> a -> b
$ JpgUnpackerParameter -> HuffmanPackedTree
acHuffmanTree JpgUnpackerParameter
params
            case (Int, Int)
rrrrssss of
                (Int
0xF, Int
0) -> Int -> StateT BoolState (ST s) Int32
unpack forall a b. (a -> b) -> a -> b
$ Int
n forall a. Num a => a -> a -> a
+ Int
16
                (  Int
0, Int
0) -> forall (m :: * -> *) a. Monad m => a -> m a
return Int32
0
                (  Int
r, Int
0) -> forall {a}. (Num a, Bits a) => a -> a
eobrun forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s. Int -> BoolReader s Int32
unpackInt Int
r
                    where eobrun :: a -> a
eobrun a
lowBits = (a
1 forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
r) forall a. Num a => a -> a -> a
- a
1 forall a. Num a => a -> a -> a
+ a
lowBits
                (  Int
r, Int
s) -> do
                    let n' :: Int
n' = Int
n forall a. Num a => a -> a -> a
+ Int
r
                    Int32
val <- (forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
low) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s. Int -> BoolReader s Int32
decodeInt Int
s
                    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MutableMacroBlock s Int16
block forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`MS.unsafeWrite` Int
n') forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
val
                    Int -> StateT BoolState (ST s) Int32
unpack forall a b. (a -> b) -> a -> b
$ Int
n' forall a. Num a => a -> a -> a
+ Int
1

decodeRefineAc :: forall a s. JpgUnpackerParameter
               -> a
               -> MutableMacroBlock s Int16
               -> Int32
               -> BoolReader s Int32
decodeRefineAc :: forall a s.
JpgUnpackerParameter
-> a -> MutableMacroBlock s Int16 -> Int32 -> BoolReader s Int32
decodeRefineAc JpgUnpackerParameter
params a
_ MutableMacroBlock s Int16
block Int32
eobrun
        | Int32
eobrun forall a. Eq a => a -> a -> Bool
== Int32
0 = Int -> StateT BoolState (ST s) Int32
unpack Int
startIndex
        | Bool
otherwise   = Int -> StateT BoolState (ST s) ()
performEobRun Int
startIndex forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return (Int32
eobrun forall a. Num a => a -> a -> a
- Int32
1)
  where (Int
startIndex, Int
maxIndex) = JpgUnpackerParameter -> (Int, Int)
coefficientRange JpgUnpackerParameter
params
        (Int
low, Int
_) = JpgUnpackerParameter -> (Int, Int)
successiveApprox JpgUnpackerParameter
params
        plusOne :: Int16
plusOne = Int16
1 forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
low
        minusOne :: Int16
minusOne = (-Int16
1) forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
low

        getBitVal :: StateT BoolState (ST s) Int16
getBitVal = do
            Bool
v <- forall s. BoolReader s Bool
getNextBitJpg
            forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ if Bool
v then Int16
plusOne else Int16
minusOne

        performEobRun :: Int -> StateT BoolState (ST s) ()
performEobRun Int
idx | Int
idx forall a. Ord a => a -> a -> Bool
> Int
maxIndex = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
        performEobRun Int
idx = do
          Int16
coeff <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ MutableMacroBlock s Int16
block forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`MS.unsafeRead` Int
idx
          if Int16
coeff forall a. Eq a => a -> a -> Bool
/= Int16
0 then do
            Bool
bit <- forall s. BoolReader s Bool
getNextBitJpg
            case (Bool
bit, (Int16
coeff forall a. Bits a => a -> a -> a
.&. Int16
plusOne) forall a. Eq a => a -> a -> Bool
== Int16
0) of
               (Bool
False, Bool
_)    -> Int -> StateT BoolState (ST s) ()
performEobRun forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
+ Int
1
               (Bool
True, Bool
False) -> Int -> StateT BoolState (ST s) ()
performEobRun forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
+ Int
1
               (Bool
True, Bool
True) -> do
                   let newVal :: Int16
newVal | Int16
coeff forall a. Ord a => a -> a -> Bool
>= Int16
0 = Int16
coeff forall a. Num a => a -> a -> a
+ Int16
plusOne
                              | Bool
otherwise = Int16
coeff forall a. Num a => a -> a -> a
+ Int16
minusOne
                   forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ (MutableMacroBlock s Int16
block forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`MS.unsafeWrite` Int
idx) Int16
newVal
                   Int -> StateT BoolState (ST s) ()
performEobRun forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
+ Int
1
          else
            Int -> StateT BoolState (ST s) ()
performEobRun forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
+ Int
1

        unpack :: Int -> StateT BoolState (ST s) Int32
unpack Int
idx | Int
idx forall a. Ord a => a -> a -> Bool
> Int
maxIndex = forall (f :: * -> *) a. Applicative f => a -> f a
pure Int32
0
        unpack Int
idx = do
            (Int, Int)
rrrrssss <- forall s. HuffmanPackedTree -> BoolReader s (Int, Int)
decodeRrrrSsss forall a b. (a -> b) -> a -> b
$ JpgUnpackerParameter -> HuffmanPackedTree
acHuffmanTree JpgUnpackerParameter
params
            case (Int, Int)
rrrrssss of
              (Int
0xF, Int
0) -> do
                Int
idx' <- Int -> Int -> BoolReader s Int
updateCoeffs Int
0xF Int
idx
                Int -> StateT BoolState (ST s) Int32
unpack forall a b. (a -> b) -> a -> b
$ Int
idx' forall a. Num a => a -> a -> a
+ Int
1

              (  Int
r, Int
0) -> do
                  Int32
lowBits <- forall s. Int -> BoolReader s Int32
unpackInt Int
r
                  let newEobRun :: Int32
newEobRun = (Int32
1 forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
r) forall a. Num a => a -> a -> a
+ Int32
lowBits forall a. Num a => a -> a -> a
- Int32
1
                  Int -> StateT BoolState (ST s) ()
performEobRun Int
idx
                  forall (f :: * -> *) a. Applicative f => a -> f a
pure Int32
newEobRun

              (  Int
r, Int
_) -> do
                  Int16
val <- forall {s}. StateT BoolState (ST s) Int16
getBitVal
                  Int
idx' <- Int -> Int -> BoolReader s Int
updateCoeffs (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
r) Int
idx
                  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
idx' forall a. Ord a => a -> a -> Bool
<= Int
maxIndex) forall a b. (a -> b) -> a -> b
$
                       forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ (MutableMacroBlock s Int16
block forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`MS.unsafeWrite` Int
idx') Int16
val
                  Int -> StateT BoolState (ST s) Int32
unpack forall a b. (a -> b) -> a -> b
$ Int
idx' forall a. Num a => a -> a -> a
+ Int
1

        updateCoeffs :: Int -> Int -> BoolReader s Int
        updateCoeffs :: Int -> Int -> BoolReader s Int
updateCoeffs Int
r Int
idx
            | Int
r   forall a. Ord a => a -> a -> Bool
< Int
0        = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
- Int
1
            | Int
idx forall a. Ord a => a -> a -> Bool
> Int
maxIndex = forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
idx
        updateCoeffs Int
r Int
idx = do
          Int16
coeff <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ MutableMacroBlock s Int16
block forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`MS.unsafeRead` Int
idx
          if Int16
coeff forall a. Eq a => a -> a -> Bool
/= Int16
0 then do
            Bool
bit <- forall s. BoolReader s Bool
getNextBitJpg
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
bit Bool -> Bool -> Bool
&& Int16
coeff forall a. Bits a => a -> a -> a
.&. Int16
plusOne forall a. Eq a => a -> a -> Bool
== Int16
0) forall a b. (a -> b) -> a -> b
$ do
              let writeCoeff :: Int16
writeCoeff | Int16
coeff forall a. Ord a => a -> a -> Bool
>= Int16
0 = Int16
coeff forall a. Num a => a -> a -> a
+ Int16
plusOne
                             | Bool
otherwise = Int16
coeff forall a. Num a => a -> a -> a
+ Int16
minusOne
              forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ (MutableMacroBlock s Int16
block forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`MS.unsafeWrite` Int
idx) Int16
writeCoeff
            Int -> Int -> BoolReader s Int
updateCoeffs Int
r forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
+ Int
1
          else
            Int -> Int -> BoolReader s Int
updateCoeffs (Int
r forall a. Num a => a -> a -> a
- Int
1) forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
+ Int
1

type Unpacker s =
    JpgUnpackerParameter -> MS.STVector s Int16 -> MutableMacroBlock s Int16 -> Int32
        -> BoolReader s Int32


prepareUnpacker :: [([(JpgUnpackerParameter, a)], L.ByteString)]
                -> ST s ( V.Vector (V.Vector (JpgUnpackerParameter, Unpacker s))
                        , M.STVector s BoolState)
prepareUnpacker :: forall a s.
[([(JpgUnpackerParameter, a)], ByteString)]
-> ST
     s
     (Vector (Vector (JpgUnpackerParameter, Unpacker s)),
      STVector s BoolState)
prepareUnpacker [([(JpgUnpackerParameter, a)], ByteString)]
lst = do
    let boolStates :: Vector BoolState
boolStates = forall a. [a] -> Vector a
V.fromList forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd forall {s}.
[(Vector
    (JpgUnpackerParameter,
     JpgUnpackerParameter
     -> STVector s Int16
     -> STVector s Int16
     -> Int32
     -> BoolReader s Int32),
  BoolState)]
infos
    STVector s BoolState
vec <- forall (m :: * -> *) a.
PrimMonad m =>
Vector a -> m (MVector (PrimState m) a)
V.unsafeThaw Vector BoolState
boolStates
    forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. [a] -> Vector a
V.fromList forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst forall {s}.
[(Vector
    (JpgUnpackerParameter,
     JpgUnpackerParameter
     -> STVector s Int16
     -> STVector s Int16
     -> Int32
     -> BoolReader s Int32),
  BoolState)]
infos, STVector s BoolState
vec)
  where infos :: [(Vector
    (JpgUnpackerParameter,
     JpgUnpackerParameter
     -> STVector s Int16
     -> STVector s Int16
     -> Int32
     -> BoolReader s Int32),
  BoolState)]
infos = forall a b. (a -> b) -> [a] -> [b]
map forall {b} {s}.
([(JpgUnpackerParameter, b)], ByteString)
-> (Vector
      (JpgUnpackerParameter,
       JpgUnpackerParameter
       -> STVector s Int16
       -> STVector s Int16
       -> Int32
       -> BoolReader s Int32),
    BoolState)
prepare [([(JpgUnpackerParameter, a)], ByteString)]
lst
        prepare :: ([(JpgUnpackerParameter, b)], ByteString)
-> (Vector
      (JpgUnpackerParameter,
       JpgUnpackerParameter
       -> STVector s Int16
       -> STVector s Int16
       -> Int32
       -> BoolReader s Int32),
    BoolState)
prepare ([], ByteString
_) = forall a. HasCallStack => [Char] -> a
error [Char]
"progressiveUnpack, no component"
        prepare (whole :: [(JpgUnpackerParameter, b)]
whole@((JpgUnpackerParameter
param, b
_) : [(JpgUnpackerParameter, b)]
_) , ByteString
byteString) =
         (forall a. [a] -> Vector a
V.fromList forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (\(JpgUnpackerParameter
p,b
_) -> (JpgUnpackerParameter
p, forall s.
JpgUnpackerParameter
-> STVector s Int16
-> STVector s Int16
-> Int32
-> BoolReader s Int32
unpacker)) [(JpgUnpackerParameter, b)]
whole, BoolState
boolReader)
           where unpacker :: JpgUnpackerParameter
-> STVector s Int16
-> STVector s Int16
-> Int32
-> BoolReader s Int32
unpacker = forall {a} {a} {a} {b} {s}.
(Eq a, Eq a, Num a, Num a) =>
(a, a)
-> (a, b)
-> JpgUnpackerParameter
-> STVector s Int16
-> STVector s Int16
-> Int32
-> BoolReader s Int32
selection (JpgUnpackerParameter -> (Int, Int)
successiveApprox JpgUnpackerParameter
param) (JpgUnpackerParameter -> (Int, Int)
coefficientRange JpgUnpackerParameter
param)
                 boolReader :: BoolState
boolReader = ByteString -> BoolState
initBoolStateJpg forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
B.concat forall a b. (a -> b) -> a -> b
$ ByteString -> [ByteString]
L.toChunks ByteString
byteString

                 selection :: (a, a)
-> (a, b)
-> JpgUnpackerParameter
-> STVector s Int16
-> STVector s Int16
-> Int32
-> BoolReader s Int32
selection (a
_, a
0) (a
0, b
_) = forall s.
JpgUnpackerParameter
-> STVector s Int16
-> STVector s Int16
-> Int32
-> BoolReader s Int32
decodeFirstDC
                 selection (a
_, a
0) (a, b)
_      = forall a s.
JpgUnpackerParameter
-> a -> MutableMacroBlock s Int16 -> Int32 -> BoolReader s Int32
decodeFirstAc
                 selection (a, a)
_      (a
0, b
_) = forall a s.
JpgUnpackerParameter
-> a -> MutableMacroBlock s Int16 -> Int32 -> BoolReader s Int32
decodeRefineDc
                 selection (a, a)
_      (a, b)
_      = forall a s.
JpgUnpackerParameter
-> a -> MutableMacroBlock s Int16 -> Int32 -> BoolReader s Int32
decodeRefineAc

data ComponentData s = ComponentData
  { forall s. ComponentData s -> Vector (Vector Int)
componentIndices    :: V.Vector (VS.Vector Int)
  , forall s. ComponentData s -> Vector (MutableMacroBlock s Int16)
componentBlocks     :: V.Vector (MutableMacroBlock s Int16)
  , forall s. ComponentData s -> Int
componentId         :: !Int
  , forall s. ComponentData s -> Int
componentBlockCount :: !Int
  }

-- | Iteration from 0 to n in monadic context, without data

-- keeping.

lineMap :: (Monad m) => Int -> (Int -> m ()) -> m ()
{-# INLINE lineMap #-}
lineMap :: forall (m :: * -> *). Monad m => Int -> (Int -> m ()) -> m ()
lineMap Int
count Int -> m ()
f = Int -> m ()
go Int
0
  where go :: Int -> m ()
go Int
n | Int
n forall a. Ord a => a -> a -> Bool
>= Int
count = forall (m :: * -> *) a. Monad m => a -> m a
return ()
        go Int
n = Int -> m ()
f Int
n forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> m ()
go (Int
n forall a. Num a => a -> a -> a
+ Int
1)

progressiveUnpack :: (Int, Int)
                  -> JpgFrameHeader
                  -> V.Vector (MacroBlock Int16)
                  -> [([(JpgUnpackerParameter, a)], L.ByteString)]
                  -> ST s (MutableImage s PixelYCbCr8)
progressiveUnpack :: forall a s.
(Int, Int)
-> JpgFrameHeader
-> Vector (MacroBlock Int16)
-> [([(JpgUnpackerParameter, a)], ByteString)]
-> ST s (MutableImage s PixelYCbCr8)
progressiveUnpack (Int
maxiW, Int
maxiH) JpgFrameHeader
frame Vector (MacroBlock Int16)
quants [([(JpgUnpackerParameter, a)], ByteString)]
lst = do
    (Vector (Vector (JpgUnpackerParameter, Unpacker s))
unpackers, STVector s BoolState
readers) <- forall a s.
[([(JpgUnpackerParameter, a)], ByteString)]
-> ST
     s
     (Vector (Vector (JpgUnpackerParameter, Unpacker s)),
      STVector s BoolState)
prepareUnpacker [([(JpgUnpackerParameter, a)], ByteString)]
lst
    [ComponentData s]
allBlocks <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall {s}. (Int, JpgComponent) -> ST s (ComponentData s)
allocateWorkingBlocks forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> [JpgComponent]
jpgComponents JpgFrameHeader
frame
                    :: ST s [ComponentData s]
    let scanCount :: Int
scanCount = forall (t :: * -> *) a. Foldable t => t a -> Int
length [([(JpgUnpackerParameter, a)], ByteString)]
lst
        restartIntervalValue :: Int
restartIntervalValue = case [([(JpgUnpackerParameter, a)], ByteString)]
lst of
                ((JpgUnpackerParameter
p,a
_):[(JpgUnpackerParameter, a)]
_,ByteString
_): [([(JpgUnpackerParameter, a)], ByteString)]
_ -> JpgUnpackerParameter -> Int
restartInterval JpgUnpackerParameter
p
                [([(JpgUnpackerParameter, a)], ByteString)]
_ -> -Int
1
    MVector s Int16
dcCoeffs <- forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> a -> m (MVector (PrimState m) a)
MS.replicate Int
imgComponentCount Int16
0
    MVector s Int32
eobRuns <- forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> a -> m (MVector (PrimState m) a)
MS.replicate (forall (t :: * -> *) a. Foldable t => t a -> Int
length [([(JpgUnpackerParameter, a)], ByteString)]
lst) Int32
0
    MVector s Int16
workBlock <- forall a s. (Storable a, Num a) => ST s (MutableMacroBlock s a)
createEmptyMutableMacroBlock
    MVector s Int
writeIndices <- forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> a -> m (MVector (PrimState m) a)
MS.replicate Int
imgComponentCount (Int
0 :: Int)
    MVector s Int
restartIntervals <- forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> a -> m (MVector (PrimState m) a)
MS.replicate Int
scanCount Int
restartIntervalValue
    let elementCount :: Int
elementCount = Int
imgWidth forall a. Num a => a -> a -> a
* Int
imgHeight forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
imgComponentCount
    MutableImage s PixelYCbCr8
img <- forall s a.
Int -> Int -> STVector s (PixelBaseComponent a) -> MutableImage s a
MutableImage Int
imgWidth Int
imgHeight forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> a -> m (MVector (PrimState m) a)
MS.replicate Int
elementCount Word8
128

    let processRestartInterval :: ST s ()
processRestartInterval =
          forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0 .. Int
scanCount forall a. Num a => a -> a -> a
- Int
1] forall a b. (a -> b) -> a -> b
$ \Int
ix -> do
            Int
v <- MVector s Int
restartIntervals forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`MS.read` Int
ix
            if Int
v forall a. Eq a => a -> a -> Bool
== Int
0 then do
              -- reset DC prediction

              forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
ix forall a. Eq a => a -> a -> Bool
== Int
0) (forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> a -> m ()
MS.set MVector s Int16
dcCoeffs Int16
0)
              BoolState
reader <- STVector s BoolState
readers forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
`M.read` Int
ix
              (Int32
_, BoolState
updated) <- forall s a. BoolState -> BoolReader s a -> ST s (a, BoolState)
runBoolReaderWith BoolState
reader forall a b. (a -> b) -> a -> b
$
                  forall s. BoolReader s ()
byteAlignJpg forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s. BoolReader s Int32
decodeRestartInterval
              (STVector s BoolState
readers forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.write` Int
ix) BoolState
updated 
              (MVector s Int32
eobRuns forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`MS.unsafeWrite` Int
ix) Int32
0
              (MVector s Int
restartIntervals forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`MS.unsafeWrite` Int
ix) forall a b. (a -> b) -> a -> b
$ Int
restartIntervalValue forall a. Num a => a -> a -> a
- Int
1
            else
              (MVector s Int
restartIntervals forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`MS.unsafeWrite` Int
ix) forall a b. (a -> b) -> a -> b
$ Int
v forall a. Num a => a -> a -> a
- Int
1


    forall (m :: * -> *). Monad m => Int -> (Int -> m ()) -> m ()
lineMap Int
imageMcuHeight forall a b. (a -> b) -> a -> b
$ \Int
mmY -> do
      -- Reset all blocks to 0

      forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [ComponentData s]
allBlocks forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_ (forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> a -> m ()
`MS.set` Int16
0) forall b c a. (b -> c) -> (a -> b) -> a -> c
.  forall s. ComponentData s -> Vector (MutableMacroBlock s Int16)
componentBlocks
      forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> a -> m ()
MS.set MVector s Int
writeIndices Int
0

      forall (m :: * -> *). Monad m => Int -> (Int -> m ()) -> m ()
lineMap Int
imageMcuWidth forall a b. (a -> b) -> a -> b
$ \Int
_mmx -> do
        ST s ()
processRestartInterval 
        forall (m :: * -> *) a b. Monad m => Vector a -> (a -> m b) -> m ()
V.forM_ Vector (Vector (JpgUnpackerParameter, Unpacker s))
unpackers forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_ forall a b. (a -> b) -> a -> b
$ \(JpgUnpackerParameter
unpackParam, Unpacker s
unpacker) -> do
            BoolState
boolState <- STVector s BoolState
readers forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
`M.read` JpgUnpackerParameter -> Int
readerIndex JpgUnpackerParameter
unpackParam
            Int32
eobrun <- MVector s Int32
eobRuns forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`MS.read` JpgUnpackerParameter -> Int
readerIndex JpgUnpackerParameter
unpackParam
            let componentNumber :: Int
componentNumber = JpgUnpackerParameter -> Int
componentIndex JpgUnpackerParameter
unpackParam
            Int
writeIndex <- MVector s Int
writeIndices forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`MS.read` Int
componentNumber
            let componentData :: ComponentData s
componentData = [ComponentData s]
allBlocks forall a. [a] -> Int -> a
!! Int
componentNumber
                -- We get back the correct block indices for the number of component

                -- in the current scope (precalculated)

                indexVector :: Vector Int
indexVector =
                    forall s. ComponentData s -> Vector (Vector Int)
componentIndices ComponentData s
componentData forall a. Vector a -> Int -> a
! JpgUnpackerParameter -> Int
indiceVector JpgUnpackerParameter
unpackParam
                maxIndexLength :: Int
maxIndexLength = forall a. Storable a => Vector a -> Int
VS.length Vector Int
indexVector
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
writeIndex forall a. Num a => a -> a -> a
+ JpgUnpackerParameter -> Int
blockIndex JpgUnpackerParameter
unpackParam forall a. Ord a => a -> a -> Bool
>= Int
maxIndexLength) forall a b. (a -> b) -> a -> b
$ do
               let realIndex :: Int
realIndex = Vector Int
indexVector forall a. Storable a => Vector a -> Int -> a
VS.! (Int
writeIndex forall a. Num a => a -> a -> a
+ JpgUnpackerParameter -> Int
blockIndex JpgUnpackerParameter
unpackParam)
                   writeBlock :: MVector s Int16
writeBlock = forall s. ComponentData s -> Vector (MutableMacroBlock s Int16)
componentBlocks ComponentData s
componentData forall a. Vector a -> Int -> a
! Int
realIndex
               (Int32
eobrun', BoolState
state) <-
                   forall s a. BoolState -> BoolReader s a -> ST s (a, BoolState)
runBoolReaderWith BoolState
boolState forall a b. (a -> b) -> a -> b
$
                       Unpacker s
unpacker JpgUnpackerParameter
unpackParam MVector s Int16
dcCoeffs MVector s Int16
writeBlock Int32
eobrun

               (STVector s BoolState
readers forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.write` JpgUnpackerParameter -> Int
readerIndex JpgUnpackerParameter
unpackParam) BoolState
state
               (MVector s Int32
eobRuns forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`MS.write` JpgUnpackerParameter -> Int
readerIndex JpgUnpackerParameter
unpackParam) Int32
eobrun'

        -- Update the write indices

        forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [ComponentData s]
allBlocks forall a b. (a -> b) -> a -> b
$ \ComponentData s
comp -> do
          Int
writeIndex <- MVector s Int
writeIndices forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`MS.read` forall s. ComponentData s -> Int
componentId ComponentData s
comp
          let newIndex :: Int
newIndex = Int
writeIndex forall a. Num a => a -> a -> a
+ forall s. ComponentData s -> Int
componentBlockCount ComponentData s
comp
          (MVector s Int
writeIndices forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`MS.write` forall s. ComponentData s -> Int
componentId ComponentData s
comp) Int
newIndex

      forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [ComponentData s]
allBlocks forall a b. (a -> b) -> a -> b
$ \ComponentData s
compData -> do
        let compBlocks :: Vector (MVector s Int16)
compBlocks = forall s. ComponentData s -> Vector (MutableMacroBlock s Int16)
componentBlocks ComponentData s
compData
            cId :: Int
cId = forall s. ComponentData s -> Int
componentId ComponentData s
compData
            comp :: JpgComponent
comp = JpgFrameHeader -> [JpgComponent]
jpgComponents JpgFrameHeader
frame forall a. [a] -> Int -> a
!! Int
cId
            quantId :: Int
quantId =
                forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ JpgComponent -> Word8
quantizationTableDest JpgComponent
comp
            table :: MacroBlock Int16
table = Vector (MacroBlock Int16)
quants forall a. Vector a -> Int -> a
! forall a. Ord a => a -> a -> a
min Int
3 Int
quantId
            compW :: Int
compW = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ JpgComponent -> Word8
horizontalSamplingFactor JpgComponent
comp
            compH :: Int
compH = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ JpgComponent -> Word8
verticalSamplingFactor JpgComponent
comp
            cw8 :: Int
cw8 = Int
maxiW forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fromIntegral (JpgComponent -> Word8
horizontalSamplingFactor JpgComponent
comp) forall a. Num a => a -> a -> a
+ Int
1
            ch8 :: Int
ch8 = Int
maxiH forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fromIntegral (JpgComponent -> Word8
verticalSamplingFactor JpgComponent
comp) forall a. Num a => a -> a -> a
+ Int
1

        forall (m :: * -> *).
Monad m =>
Int -> Int -> (Int -> Int -> m ()) -> m ()
rasterMap (Int
imageMcuWidth forall a. Num a => a -> a -> a
* Int
compW) Int
compH forall a b. (a -> b) -> a -> b
$ \Int
rx Int
y -> do
            let ry :: Int
ry = Int
mmY forall a. Num a => a -> a -> a
* Int
maxiH forall a. Num a => a -> a -> a
+ Int
y
                block :: MVector s Int16
block = Vector (MVector s Int16)
compBlocks forall a. Vector a -> Int -> a
! (Int
y forall a. Num a => a -> a -> a
* Int
imageMcuWidth forall a. Num a => a -> a -> a
* Int
compW forall a. Num a => a -> a -> a
+ Int
rx)
            MVector s Int16
transformed <- forall s.
MacroBlock Int16
-> MutableMacroBlock s Int16
-> MutableMacroBlock s Int16
-> ST s (MutableMacroBlock s Int16)
decodeMacroBlock MacroBlock Int16
table MVector s Int16
workBlock MVector s Int16
block
            forall s.
Int
-> Int
-> Int
-> Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
unpackMacroBlock Int
imgComponentCount
                    Int
cw8 Int
ch8 Int
cId (Int
rx forall a. Num a => a -> a -> a
* Int
cw8) Int
ry
                    MutableImage s PixelYCbCr8
img MVector s Int16
transformed

    forall (m :: * -> *) a. Monad m => a -> m a
return MutableImage s PixelYCbCr8
img

  where imgComponentCount :: Int
imgComponentCount = forall (t :: * -> *) a. Foldable t => t a -> Int
length forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> [JpgComponent]
jpgComponents JpgFrameHeader
frame

        imgWidth :: Int
imgWidth = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> Word16
jpgWidth JpgFrameHeader
frame
        imgHeight :: Int
imgHeight = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> Word16
jpgHeight JpgFrameHeader
frame

        imageBlockWidth :: Int
imageBlockWidth = Int -> Int
toBlockSize Int
imgWidth
        imageBlockHeight :: Int
imageBlockHeight = Int -> Int
toBlockSize Int
imgHeight

        imageMcuWidth :: Int
imageMcuWidth =  (Int
imageBlockWidth forall a. Num a => a -> a -> a
+ (Int
maxiW forall a. Num a => a -> a -> a
- Int
1)) forall a. Integral a => a -> a -> a
`div` Int
maxiW
        imageMcuHeight :: Int
imageMcuHeight = (Int
imageBlockHeight forall a. Num a => a -> a -> a
+ (Int
maxiH forall a. Num a => a -> a -> a
- Int
1)) forall a. Integral a => a -> a -> a
`div` Int
maxiH

        allocateWorkingBlocks :: (Int, JpgComponent) -> ST s (ComponentData s)
allocateWorkingBlocks (Int
ix, JpgComponent
comp) = do
            let blockCount :: Int
blockCount = Int
hSample forall a. Num a => a -> a -> a
* Int
vSample forall a. Num a => a -> a -> a
* Int
imageMcuWidth forall a. Num a => a -> a -> a
* Int
2
            Vector (MutableMacroBlock s Int16)
blocks <- forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
blockCount forall a s. (Storable a, Num a) => ST s (MutableMacroBlock s a)
createEmptyMutableMacroBlock
            forall (m :: * -> *) a. Monad m => a -> m a
return ComponentData 
                { componentBlocks :: Vector (MutableMacroBlock s Int16)
componentBlocks = Vector (MutableMacroBlock s Int16)
blocks
                , componentIndices :: Vector (Vector Int)
componentIndices = JpgComponent -> Int -> Int -> Vector (Vector Int)
createMcuLineIndices JpgComponent
comp Int
imgWidth Int
imageMcuWidth
                , componentBlockCount :: Int
componentBlockCount = Int
hSample forall a. Num a => a -> a -> a
* Int
vSample
                , componentId :: Int
componentId = Int
ix
                }
            where hSample :: Int
hSample = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ JpgComponent -> Word8
horizontalSamplingFactor JpgComponent
comp
                  vSample :: Int
vSample = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ JpgComponent -> Word8
verticalSamplingFactor JpgComponent
comp