{-# LANGUAGE TupleSections #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -fspec-constr-count=5 #-}
module Codec.Picture.Jpg( decodeJpeg
, decodeJpegWithMetadata
, encodeJpegAtQuality
, encodeJpegAtQualityWithMetadata
, encodeDirectJpegAtQualityWithMetadata
, encodeJpeg
, JpgEncodable
) where
#if !MIN_VERSION_base(4,8,0)
import Data.Foldable( foldMap )
import Data.Monoid( mempty )
import Control.Applicative( pure, (<$>) )
#endif
import Control.Applicative( (<|>) )
import Control.Arrow( (>>>) )
import Control.Monad( when, forM_ )
import Control.Monad.ST( ST, runST )
import Control.Monad.Trans( lift )
import Control.Monad.Trans.RWS.Strict( RWS, modify, tell, gets, execRWS )
import Data.Bits( (.|.), unsafeShiftL )
#if !MIN_VERSION_base(4,11,0)
import Data.Monoid( (<>) )
#endif
import Data.Int( Int16, Int32 )
import Data.Word(Word8, Word32)
import Data.Binary( Binary(..), encode )
import Data.STRef( newSTRef, writeSTRef, readSTRef )
import Data.Vector( (//) )
import Data.Vector.Unboxed( (!) )
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Storable as VS
import qualified Data.Vector.Storable.Mutable as M
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
import Codec.Picture.InternalHelper
import Codec.Picture.BitWriter
import Codec.Picture.Types
import Codec.Picture.Metadata( Metadatas
, SourceFormat( SourceJpeg )
, basicMetadata )
import Codec.Picture.Tiff.Internal.Types
import Codec.Picture.Tiff.Internal.Metadata
import Codec.Picture.Jpg.Internal.Types
import Codec.Picture.Jpg.Internal.Common
import Codec.Picture.Jpg.Internal.Progressive
import Codec.Picture.Jpg.Internal.DefaultTable
import Codec.Picture.Jpg.Internal.FastDct
import Codec.Picture.Jpg.Internal.Metadata
quantize :: MacroBlock Int16 -> MutableMacroBlock s Int32
-> ST s (MutableMacroBlock s Int32)
quantize :: forall s.
MacroBlock Int16
-> MutableMacroBlock s Int32 -> ST s (MutableMacroBlock s Int32)
quantize MacroBlock Int16
table MutableMacroBlock s Int32
block = Int -> ST s (MutableMacroBlock s Int32)
update Int
0
where update :: Int -> ST s (MutableMacroBlock s Int32)
update Int
64 = MutableMacroBlock s Int32 -> ST s (MutableMacroBlock s Int32)
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return MutableMacroBlock s Int32
block
update Int
idx = do
Int32
val <- MutableMacroBlock s Int32
MVector (PrimState (ST s)) Int32
block MVector (PrimState (ST s)) Int32 -> Int -> ST s Int32
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` Int
idx
let q :: Int32
q = Int16 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (MacroBlock Int16
table MacroBlock Int16 -> Int -> Int16
forall a. Storable a => Vector a -> Int -> a
`VS.unsafeIndex` Int
idx)
finalValue :: Int32
finalValue = (Int32
val Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
+ (Int32
q Int32 -> Int32 -> Int32
forall a. Integral a => a -> a -> a
`div` Int32
2)) Int32 -> Int32 -> Int32
forall a. Integral a => a -> a -> a
`quot` Int32
q
(MutableMacroBlock s Int32
MVector (PrimState (ST s)) Int32
block MVector (PrimState (ST s)) Int32 -> Int -> Int32 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` Int
idx) Int32
finalValue
Int -> ST s (MutableMacroBlock s Int32)
update (Int -> ST s (MutableMacroBlock s Int32))
-> Int -> ST s (MutableMacroBlock s Int32)
forall a b. (a -> b) -> a -> b
$ Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
powerOf :: Int32 -> Word32
powerOf :: Int32 -> Word32
powerOf Int32
0 = Word32
0
powerOf Int32
n = Int32 -> Word32 -> Word32
limit Int32
1 Word32
0
where val :: Int32
val = Int32 -> Int32
forall a. Num a => a -> a
abs Int32
n
limit :: Int32 -> Word32 -> Word32
limit Int32
range Word32
i | Int32
val Int32 -> Int32 -> Bool
forall a. Ord a => a -> a -> Bool
< Int32
range = Word32
i
limit Int32
range Word32
i = Int32 -> Word32 -> Word32
limit (Int32
2 Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
* Int32
range) (Word32
i Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
1)
encodeInt :: BoolWriteStateRef s -> Word32 -> Int32 -> ST s ()
{-# INLINE encodeInt #-}
encodeInt :: forall s. BoolWriteStateRef s -> Word32 -> Int32 -> ST s ()
encodeInt BoolWriteStateRef s
st Word32
ssss Int32
n | Int32
n Int32 -> Int32 -> Bool
forall a. Ord a => a -> a -> Bool
> Int32
0 = BoolWriteStateRef s -> Word32 -> Int -> ST s ()
forall s. BoolWriteStateRef s -> Word32 -> Int -> ST s ()
writeBits' BoolWriteStateRef s
st (Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
n) (Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
ssss)
encodeInt BoolWriteStateRef s
st Word32
ssss Int32
n = BoolWriteStateRef s -> Word32 -> Int -> ST s ()
forall s. BoolWriteStateRef s -> Word32 -> Int -> ST s ()
writeBits' BoolWriteStateRef s
st (Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32 -> Word32) -> Int32 -> Word32
forall a b. (a -> b) -> a -> b
$ Int32
n Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
- Int32
1) (Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
ssss)
acCoefficientsDecode :: HuffmanPackedTree -> MutableMacroBlock s Int16
-> BoolReader s (MutableMacroBlock s Int16)
acCoefficientsDecode :: forall s.
HuffmanPackedTree
-> MutableMacroBlock s Int16
-> BoolReader s (MutableMacroBlock s Int16)
acCoefficientsDecode HuffmanPackedTree
acTree MutableMacroBlock s Int16
mutableBlock = Int -> StateT BoolState (ST s) ()
parseAcCoefficient Int
1 StateT BoolState (ST s) ()
-> StateT BoolState (ST s) (MutableMacroBlock s Int16)
-> StateT BoolState (ST s) (MutableMacroBlock s Int16)
forall a b.
StateT BoolState (ST s) a
-> StateT BoolState (ST s) b -> StateT BoolState (ST s) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MutableMacroBlock s Int16
-> StateT BoolState (ST s) (MutableMacroBlock s Int16)
forall a. a -> StateT BoolState (ST s) a
forall (m :: * -> *) a. Monad m => a -> m a
return MutableMacroBlock s Int16
mutableBlock
where parseAcCoefficient :: Int -> StateT BoolState (ST s) ()
parseAcCoefficient Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
64 = () -> StateT BoolState (ST s) ()
forall a. a -> StateT BoolState (ST s) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = do
(Int, Int)
rrrrssss <- HuffmanPackedTree -> BoolReader s (Int, Int)
forall s. HuffmanPackedTree -> BoolReader s (Int, Int)
decodeRrrrSsss HuffmanPackedTree
acTree
case (Int, Int)
rrrrssss of
( Int
0, Int
0) -> () -> StateT BoolState (ST s) ()
forall a. a -> StateT BoolState (ST s) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
(Int
0xF, Int
0) -> Int -> StateT BoolState (ST s) ()
parseAcCoefficient (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
16)
(Int
rrrr, Int
ssss) -> do
Int16
decoded <- Int32 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32 -> Int16)
-> StateT BoolState (ST s) Int32 -> StateT BoolState (ST s) Int16
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> StateT BoolState (ST s) Int32
forall s. Int -> BoolReader s Int32
decodeInt Int
ssss
ST s () -> StateT BoolState (ST s) ()
forall (m :: * -> *) a. Monad m => m a -> StateT BoolState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s () -> StateT BoolState (ST s) ())
-> ST s () -> StateT BoolState (ST s) ()
forall a b. (a -> b) -> a -> b
$ (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
mutableBlock MVector (PrimState (ST s)) Int16 -> Int -> Int16 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
rrrr)) Int16
decoded
Int -> StateT BoolState (ST s) ()
parseAcCoefficient (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
rrrr Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
decompressMacroBlock :: HuffmanPackedTree
-> HuffmanPackedTree
-> MacroBlock Int16
-> MutableMacroBlock s Int16
-> DcCoefficient
-> BoolReader s (DcCoefficient, MutableMacroBlock s Int16)
decompressMacroBlock :: forall s.
HuffmanPackedTree
-> HuffmanPackedTree
-> MacroBlock Int16
-> MutableMacroBlock s Int16
-> Int16
-> BoolReader s (Int16, MutableMacroBlock s Int16)
decompressMacroBlock HuffmanPackedTree
dcTree HuffmanPackedTree
acTree MacroBlock Int16
quantizationTable MutableMacroBlock s Int16
zigzagBlock Int16
previousDc = do
Int16
dcDeltaCoefficient <- HuffmanPackedTree -> BoolReader s Int16
forall s. HuffmanPackedTree -> BoolReader s Int16
dcCoefficientDecode HuffmanPackedTree
dcTree
MutableMacroBlock s Int16
block <- ST s (MutableMacroBlock s Int16)
-> StateT BoolState (ST s) (MutableMacroBlock s Int16)
forall (m :: * -> *) a. Monad m => m a -> StateT BoolState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift ST s (MutableMacroBlock s Int16)
forall a s. (Storable a, Num a) => ST s (MutableMacroBlock s a)
createEmptyMutableMacroBlock
let neoDcCoefficient :: Int16
neoDcCoefficient = Int16
previousDc Int16 -> Int16 -> Int16
forall a. Num a => a -> a -> a
+ Int16
dcDeltaCoefficient
ST s () -> StateT BoolState (ST s) ()
forall (m :: * -> *) a. Monad m => m a -> StateT BoolState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s () -> StateT BoolState (ST s) ())
-> ST s () -> StateT BoolState (ST s) ()
forall a b. (a -> b) -> a -> b
$ (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> Int16 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` Int
0) Int16
neoDcCoefficient
MutableMacroBlock s Int16
fullBlock <- HuffmanPackedTree
-> MutableMacroBlock s Int16
-> StateT BoolState (ST s) (MutableMacroBlock s Int16)
forall s.
HuffmanPackedTree
-> MutableMacroBlock s Int16
-> BoolReader s (MutableMacroBlock s Int16)
acCoefficientsDecode HuffmanPackedTree
acTree MutableMacroBlock s Int16
block
MutableMacroBlock s Int16
decodedBlock <- ST s (MutableMacroBlock s Int16)
-> StateT BoolState (ST s) (MutableMacroBlock s Int16)
forall (m :: * -> *) a. Monad m => m a -> StateT BoolState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s (MutableMacroBlock s Int16)
-> StateT BoolState (ST s) (MutableMacroBlock s Int16))
-> ST s (MutableMacroBlock s Int16)
-> StateT BoolState (ST s) (MutableMacroBlock s Int16)
forall a b. (a -> b) -> a -> b
$ MacroBlock Int16
-> MutableMacroBlock s Int16
-> MutableMacroBlock s Int16
-> ST s (MutableMacroBlock s Int16)
forall s.
MacroBlock Int16
-> MutableMacroBlock s Int16
-> MutableMacroBlock s Int16
-> ST s (MutableMacroBlock s Int16)
decodeMacroBlock MacroBlock Int16
quantizationTable MutableMacroBlock s Int16
zigzagBlock MutableMacroBlock s Int16
fullBlock
(Int16, MutableMacroBlock s Int16)
-> BoolReader s (Int16, MutableMacroBlock s Int16)
forall a. a -> StateT BoolState (ST s) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int16
neoDcCoefficient, MutableMacroBlock s Int16
decodedBlock)
pixelClamp :: Int16 -> Word8
pixelClamp :: Int16 -> Word8
pixelClamp Int16
n = Int16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int16 -> Word8) -> (Int16 -> Int16) -> Int16 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int16 -> Int16 -> Int16
forall a. Ord a => a -> a -> a
min Int16
255 (Int16 -> Word8) -> Int16 -> Word8
forall a b. (a -> b) -> a -> b
$ Int16 -> Int16 -> Int16
forall a. Ord a => a -> a -> a
max Int16
0 Int16
n
unpack444Y :: Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
unpack444Y :: forall s.
Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
unpack444Y Int
_ Int
x Int
y (MutableImage { mutableImageWidth :: forall s a. MutableImage s a -> Int
mutableImageWidth = Int
imgWidth, mutableImageData :: forall s a. MutableImage s a -> STVector s (PixelBaseComponent a)
mutableImageData = STVector s (PixelBaseComponent PixelYCbCr8)
img })
MutableMacroBlock s Int16
block = Int -> Int -> Int -> ST s ()
blockVert Int
baseIdx Int
0 Int
zero
where zero :: Int
zero = Int
0 :: Int
baseIdx :: Int
baseIdx = Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
imgWidth
blockVert :: Int -> Int -> Int -> ST s ()
blockVert Int
_ Int
_ Int
j | Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
forall a. Num a => a
dctBlockSize = () -> ST s ()
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
blockVert Int
writeIdx Int
readingIdx Int
j = Int -> Int -> Int -> ST s ()
blockHoriz Int
writeIdx Int
readingIdx Int
zero
where blockHoriz :: Int -> Int -> Int -> ST s ()
blockHoriz Int
_ Int
readIdx Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
forall a. Num a => a
dctBlockSize = Int -> Int -> Int -> ST s ()
blockVert (Int
writeIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
imgWidth) Int
readIdx (Int -> ST s ()) -> Int -> ST s ()
forall a b. (a -> b) -> a -> b
$ Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
blockHoriz Int
idx Int
readIdx Int
i = do
Word8
val <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` Int
readIdx)
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` Int
idx) Word8
val
Int -> Int -> Int -> ST s ()
blockHoriz (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Int -> ST s ()) -> Int -> ST s ()
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
unpack444Ycbcr :: Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
unpack444Ycbcr :: forall s.
Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
unpack444Ycbcr Int
compIdx Int
x Int
y
(MutableImage { mutableImageWidth :: forall s a. MutableImage s a -> Int
mutableImageWidth = Int
imgWidth, mutableImageData :: forall s a. MutableImage s a -> STVector s (PixelBaseComponent a)
mutableImageData = STVector s (PixelBaseComponent PixelYCbCr8)
img })
MutableMacroBlock s Int16
block = Int -> Int -> Int -> ST s ()
blockVert Int
baseIdx Int
0 Int
zero
where zero :: Int
zero = Int
0 :: Int
baseIdx :: Int
baseIdx = (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
imgWidth) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
compIdx
blockVert :: Int -> Int -> Int -> ST s ()
blockVert Int
_ Int
_ Int
j | Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
forall a. Num a => a
dctBlockSize = () -> ST s ()
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
blockVert Int
idx Int
readIdx Int
j = do
Word8
val0 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` Int
readIdx)
Word8
val1 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
Word8
val2 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2))
Word8
val3 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3))
Word8
val4 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
4))
Word8
val5 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
5))
Word8
val6 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6))
Word8
val7 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7))
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` Int
idx) Word8
val0
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3 )) Word8
val1
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2))) Word8
val2
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3))) Word8
val3
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
4))) Word8
val4
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
5))) Word8
val5
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
6))) Word8
val6
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
7))) Word8
val7
Int -> Int -> Int -> ST s ()
blockVert (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
imgWidth) (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
forall a. Num a => a
dctBlockSize) (Int -> ST s ()) -> Int -> ST s ()
forall a b. (a -> b) -> a -> b
$ Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
unpack421Ycbcr :: Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
unpack421Ycbcr :: forall s.
Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
unpack421Ycbcr Int
compIdx Int
x Int
y
(MutableImage { mutableImageWidth :: forall s a. MutableImage s a -> Int
mutableImageWidth = Int
imgWidth,
mutableImageHeight :: forall s a. MutableImage s a -> Int
mutableImageHeight = Int
_, mutableImageData :: forall s a. MutableImage s a -> STVector s (PixelBaseComponent a)
mutableImageData = STVector s (PixelBaseComponent PixelYCbCr8)
img })
MutableMacroBlock s Int16
block = Int -> Int -> Int -> ST s ()
blockVert Int
baseIdx Int
0 Int
zero
where zero :: Int
zero = Int
0 :: Int
baseIdx :: Int
baseIdx = (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
imgWidth) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
compIdx
lineOffset :: Int
lineOffset = Int
imgWidth Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3
blockVert :: Int -> Int -> Int -> ST s ()
blockVert Int
_ Int
_ Int
j | Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
forall a. Num a => a
dctBlockSize = () -> ST s ()
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
blockVert Int
idx Int
readIdx Int
j = do
Word8
v0 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` Int
readIdx)
Word8
v1 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
Word8
v2 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2))
Word8
v3 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3))
Word8
v4 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
4))
Word8
v5 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
5))
Word8
v6 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6))
Word8
v7 <- Int16 -> Word8
pixelClamp (Int16 -> Word8) -> ST s Int16 -> ST s Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7))
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` Int
idx) Word8
v0
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3)) Word8
v0
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 )) Word8
v1
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3)) Word8
v1
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2)) Word8
v2
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3)) Word8
v2
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3)) Word8
v3
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3)) Word8
v3
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
4)) Word8
v4
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
4 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3)) Word8
v4
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
5)) Word8
v5
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
5 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3)) Word8
v5
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
6)) Word8
v6
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3)) Word8
v6
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
7)) Word8
v7
(STVector s (PixelBaseComponent PixelYCbCr8)
MVector (PrimState (ST s)) Word8
img MVector (PrimState (ST s)) Word8 -> Int -> Word8 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
7 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3)) Word8
v7
Int -> Int -> Int -> ST s ()
blockVert (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
lineOffset) (Int
readIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
forall a. Num a => a
dctBlockSize) (Int -> ST s ()) -> Int -> ST s ()
forall a b. (a -> b) -> a -> b
$ Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
type Unpacker s = Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
type JpgScripter s a =
RWS () [([(JpgUnpackerParameter, Unpacker s)], L.ByteString)] JpgDecoderState a
data JpgDecoderState = JpgDecoderState
{ JpgDecoderState -> Vector HuffmanPackedTree
dcDecoderTables :: !(V.Vector HuffmanPackedTree)
, JpgDecoderState -> Vector HuffmanPackedTree
acDecoderTables :: !(V.Vector HuffmanPackedTree)
, JpgDecoderState -> Vector (MacroBlock Int16)
quantizationMatrices :: !(V.Vector (MacroBlock Int16))
, JpgDecoderState -> Int
currentRestartInterv :: !Int
, JpgDecoderState -> Maybe JpgFrameHeader
currentFrame :: Maybe JpgFrameHeader
, JpgDecoderState -> Maybe JpgAdobeApp14
app14Marker :: !(Maybe JpgAdobeApp14)
, JpgDecoderState -> Maybe JpgJFIFApp0
app0JFifMarker :: !(Maybe JpgJFIFApp0)
, JpgDecoderState -> Maybe [ImageFileDirectory]
app1ExifMarker :: !(Maybe [ImageFileDirectory])
, JpgDecoderState -> [(Word8, Int)]
componentIndexMapping :: ![(Word8, Int)]
, JpgDecoderState -> Bool
isProgressive :: !Bool
, JpgDecoderState -> Int
maximumHorizontalResolution :: !Int
, JpgDecoderState -> Int
maximumVerticalResolution :: !Int
, JpgDecoderState -> Int
seenBlobs :: !Int
}
emptyDecoderState :: JpgDecoderState
emptyDecoderState :: JpgDecoderState
emptyDecoderState = JpgDecoderState
{ dcDecoderTables :: Vector HuffmanPackedTree
dcDecoderTables =
let (JpgHuffmanTableSpec
_, HuffmanPackedTree
dcLuma) = DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
DcComponent Word8
0 HuffmanTable
defaultDcLumaHuffmanTable
(JpgHuffmanTableSpec
_, HuffmanPackedTree
dcChroma) = DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
DcComponent Word8
1 HuffmanTable
defaultDcChromaHuffmanTable
in
[HuffmanPackedTree] -> Vector HuffmanPackedTree
forall a. [a] -> Vector a
V.fromList [ HuffmanPackedTree
dcLuma, HuffmanPackedTree
dcChroma, HuffmanPackedTree
dcLuma, HuffmanPackedTree
dcChroma ]
, acDecoderTables :: Vector HuffmanPackedTree
acDecoderTables =
let (JpgHuffmanTableSpec
_, HuffmanPackedTree
acLuma) = DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
AcComponent Word8
0 HuffmanTable
defaultAcLumaHuffmanTable
(JpgHuffmanTableSpec
_, HuffmanPackedTree
acChroma) = DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
AcComponent Word8
1 HuffmanTable
defaultAcChromaHuffmanTable
in
[HuffmanPackedTree] -> Vector HuffmanPackedTree
forall a. [a] -> Vector a
V.fromList [HuffmanPackedTree
acLuma, HuffmanPackedTree
acChroma, HuffmanPackedTree
acLuma, HuffmanPackedTree
acChroma]
, quantizationMatrices :: Vector (MacroBlock Int16)
quantizationMatrices = Int -> MacroBlock Int16 -> Vector (MacroBlock Int16)
forall a. Int -> a -> Vector a
V.replicate Int
4 (Int -> Int16 -> MacroBlock Int16
forall a. Storable a => Int -> a -> Vector a
VS.replicate (Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
8) Int16
1)
, currentRestartInterv :: Int
currentRestartInterv = -Int
1
, currentFrame :: Maybe JpgFrameHeader
currentFrame = Maybe JpgFrameHeader
forall a. Maybe a
Nothing
, componentIndexMapping :: [(Word8, Int)]
componentIndexMapping = []
, app14Marker :: Maybe JpgAdobeApp14
app14Marker = Maybe JpgAdobeApp14
forall a. Maybe a
Nothing
, app0JFifMarker :: Maybe JpgJFIFApp0
app0JFifMarker = Maybe JpgJFIFApp0
forall a. Maybe a
Nothing
, app1ExifMarker :: Maybe [ImageFileDirectory]
app1ExifMarker = Maybe [ImageFileDirectory]
forall a. Maybe a
Nothing
, isProgressive :: Bool
isProgressive = Bool
False
, maximumHorizontalResolution :: Int
maximumHorizontalResolution = Int
0
, maximumVerticalResolution :: Int
maximumVerticalResolution = Int
0
, seenBlobs :: Int
seenBlobs = Int
0
}
jpgMachineStep :: JpgFrame -> JpgScripter s ()
jpgMachineStep :: forall s. JpgFrame -> JpgScripter s ()
jpgMachineStep (JpgAdobeAPP14 JpgAdobeApp14
app14) = (JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall w (m :: * -> *) s r.
(Monoid w, Monad m) =>
(s -> s) -> RWST r w s m ()
modify ((JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
())
-> (JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall a b. (a -> b) -> a -> b
$ \JpgDecoderState
s ->
JpgDecoderState
s { app14Marker = Just app14 }
jpgMachineStep (JpgExif [ImageFileDirectory]
exif) = (JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall w (m :: * -> *) s r.
(Monoid w, Monad m) =>
(s -> s) -> RWST r w s m ()
modify ((JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
())
-> (JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall a b. (a -> b) -> a -> b
$ \JpgDecoderState
s ->
JpgDecoderState
s { app1ExifMarker = Just exif }
jpgMachineStep (JpgJFIF JpgJFIFApp0
app0) = (JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall w (m :: * -> *) s r.
(Monoid w, Monad m) =>
(s -> s) -> RWST r w s m ()
modify ((JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
())
-> (JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall a b. (a -> b) -> a -> b
$ \JpgDecoderState
s ->
JpgDecoderState
s { app0JFifMarker = Just app0 }
jpgMachineStep (JpgAppFrame Word8
_ ByteString
_) = ()
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall a.
a
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
jpgMachineStep (JpgExtension Word8
_ ByteString
_) = ()
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall a.
a
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
jpgMachineStep (JpgScanBlob JpgScanHeader
hdr ByteString
raw_data) = do
let scanCount :: Int
scanCount = [JpgScanSpecification] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([JpgScanSpecification] -> Int) -> [JpgScanSpecification] -> Int
forall a b. (a -> b) -> a -> b
$ JpgScanHeader -> [JpgScanSpecification]
scans JpgScanHeader
hdr
[(JpgUnpackerParameter, Unpacker s)]
params <- [[(JpgUnpackerParameter, Unpacker s)]]
-> [(JpgUnpackerParameter, Unpacker s)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[(JpgUnpackerParameter, Unpacker s)]]
-> [(JpgUnpackerParameter, Unpacker s)])
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
[[(JpgUnpackerParameter, Unpacker s)]]
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
[(JpgUnpackerParameter, Unpacker s)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (JpgScanSpecification
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
[(JpgUnpackerParameter, Unpacker s)])
-> [JpgScanSpecification]
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
[[(JpgUnpackerParameter, Unpacker s)]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Int
-> JpgScanSpecification
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
[(JpgUnpackerParameter, Unpacker s)]
scanSpecifier Int
scanCount) (JpgScanHeader -> [JpgScanSpecification]
scans JpgScanHeader
hdr)
(JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall w (m :: * -> *) s r.
(Monoid w, Monad m) =>
(s -> s) -> RWST r w s m ()
modify ((JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
())
-> (JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall a b. (a -> b) -> a -> b
$ \JpgDecoderState
st -> JpgDecoderState
st { seenBlobs = seenBlobs st + 1 }
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall (m :: * -> *) w r s. Monad m => w -> RWST r w s m ()
tell [([(JpgUnpackerParameter, Unpacker s)]
params, ByteString
raw_data) ]
where (Word8
selectionLow, Word8
selectionHigh) = JpgScanHeader -> (Word8, Word8)
spectralSelection JpgScanHeader
hdr
approxHigh :: Int
approxHigh = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Word8 -> Int
forall a b. (a -> b) -> a -> b
$ JpgScanHeader -> Word8
successiveApproxHigh JpgScanHeader
hdr
approxLow :: Int
approxLow = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Word8 -> Int
forall a b. (a -> b) -> a -> b
$ JpgScanHeader -> Word8
successiveApproxLow JpgScanHeader
hdr
scanSpecifier :: Int
-> JpgScanSpecification
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
[(JpgUnpackerParameter, Unpacker s)]
scanSpecifier Int
scanCount JpgScanSpecification
scanSpec = do
[(Word8, Int)]
compMapping <- (JpgDecoderState -> [(Word8, Int)])
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
[(Word8, Int)]
forall w (m :: * -> *) s a r.
(Monoid w, Monad m) =>
(s -> a) -> RWST r w s m a
gets JpgDecoderState -> [(Word8, Int)]
componentIndexMapping
Int
comp <- case Word8 -> [(Word8, Int)] -> Maybe Int
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup (JpgScanSpecification -> Word8
componentSelector JpgScanSpecification
scanSpec) [(Word8, Int)]
compMapping of
Maybe Int
Nothing -> String
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
Int
forall a. HasCallStack => String -> a
error String
"Jpg decoding error - bad component selector in blob."
Just Int
v -> Int
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
Int
forall a.
a
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
v
let maximumHuffmanTable :: Int
maximumHuffmanTable = Int
4
dcIndex :: Int
dcIndex = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Int
maximumHuffmanTable Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
(Int -> Int) -> (Word8 -> Int) -> Word8 -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Word8 -> Int
forall a b. (a -> b) -> a -> b
$ JpgScanSpecification -> Word8
dcEntropyCodingTable JpgScanSpecification
scanSpec
acIndex :: Int
acIndex = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Int
maximumHuffmanTable Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
(Int -> Int) -> (Word8 -> Int) -> Word8 -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Word8 -> Int
forall a b. (a -> b) -> a -> b
$ JpgScanSpecification -> Word8
acEntropyCodingTable JpgScanSpecification
scanSpec
HuffmanPackedTree
dcTree <- (JpgDecoderState -> HuffmanPackedTree)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
HuffmanPackedTree
forall w (m :: * -> *) s a r.
(Monoid w, Monad m) =>
(s -> a) -> RWST r w s m a
gets ((JpgDecoderState -> HuffmanPackedTree)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
HuffmanPackedTree)
-> (JpgDecoderState -> HuffmanPackedTree)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
HuffmanPackedTree
forall a b. (a -> b) -> a -> b
$ (Vector HuffmanPackedTree -> Int -> HuffmanPackedTree
forall a. Vector a -> Int -> a
V.! Int
dcIndex) (Vector HuffmanPackedTree -> HuffmanPackedTree)
-> (JpgDecoderState -> Vector HuffmanPackedTree)
-> JpgDecoderState
-> HuffmanPackedTree
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JpgDecoderState -> Vector HuffmanPackedTree
dcDecoderTables
HuffmanPackedTree
acTree <- (JpgDecoderState -> HuffmanPackedTree)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
HuffmanPackedTree
forall w (m :: * -> *) s a r.
(Monoid w, Monad m) =>
(s -> a) -> RWST r w s m a
gets ((JpgDecoderState -> HuffmanPackedTree)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
HuffmanPackedTree)
-> (JpgDecoderState -> HuffmanPackedTree)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
HuffmanPackedTree
forall a b. (a -> b) -> a -> b
$ (Vector HuffmanPackedTree -> Int -> HuffmanPackedTree
forall a. Vector a -> Int -> a
V.! Int
acIndex) (Vector HuffmanPackedTree -> HuffmanPackedTree)
-> (JpgDecoderState -> Vector HuffmanPackedTree)
-> JpgDecoderState
-> HuffmanPackedTree
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JpgDecoderState -> Vector HuffmanPackedTree
acDecoderTables
Bool
isProgressiveImage <- (JpgDecoderState -> Bool)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
Bool
forall w (m :: * -> *) s a r.
(Monoid w, Monad m) =>
(s -> a) -> RWST r w s m a
gets JpgDecoderState -> Bool
isProgressive
Int
maxiW <- (JpgDecoderState -> Int)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
Int
forall w (m :: * -> *) s a r.
(Monoid w, Monad m) =>
(s -> a) -> RWST r w s m a
gets JpgDecoderState -> Int
maximumHorizontalResolution
Int
maxiH <- (JpgDecoderState -> Int)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
Int
forall w (m :: * -> *) s a r.
(Monoid w, Monad m) =>
(s -> a) -> RWST r w s m a
gets JpgDecoderState -> Int
maximumVerticalResolution
Int
restart <- (JpgDecoderState -> Int)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
Int
forall w (m :: * -> *) s a r.
(Monoid w, Monad m) =>
(s -> a) -> RWST r w s m a
gets JpgDecoderState -> Int
currentRestartInterv
Maybe JpgFrameHeader
frameInfo <- (JpgDecoderState -> Maybe JpgFrameHeader)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
(Maybe JpgFrameHeader)
forall w (m :: * -> *) s a r.
(Monoid w, Monad m) =>
(s -> a) -> RWST r w s m a
gets JpgDecoderState -> Maybe JpgFrameHeader
currentFrame
Int
blobId <- (JpgDecoderState -> Int)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
Int
forall w (m :: * -> *) s a r.
(Monoid w, Monad m) =>
(s -> a) -> RWST r w s m a
gets JpgDecoderState -> Int
seenBlobs
case Maybe JpgFrameHeader
frameInfo of
Maybe JpgFrameHeader
Nothing -> String
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
[(JpgUnpackerParameter, Unpacker s)]
forall a. HasCallStack => String -> a
error String
"Jpg decoding error - no previous frame"
Just JpgFrameHeader
v -> do
let compDesc :: JpgComponent
compDesc = JpgFrameHeader -> [JpgComponent]
jpgComponents JpgFrameHeader
v [JpgComponent] -> Int -> JpgComponent
forall a. HasCallStack => [a] -> Int -> a
!! Int
comp
compCount :: Int
compCount = [JpgComponent] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([JpgComponent] -> Int) -> [JpgComponent] -> Int
forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> [JpgComponent]
jpgComponents JpgFrameHeader
v
xSampling :: Int
xSampling = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Word8 -> Int
forall a b. (a -> b) -> a -> b
$ JpgComponent -> Word8
horizontalSamplingFactor JpgComponent
compDesc
ySampling :: Int
ySampling = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Word8 -> Int
forall a b. (a -> b) -> a -> b
$ JpgComponent -> Word8
verticalSamplingFactor JpgComponent
compDesc
componentSubSampling :: (Int, Int)
componentSubSampling =
(Int
maxiW Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
xSampling Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, Int
maxiH Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
ySampling Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
(Int
xCount, Int
yCount)
| Int
scanCount Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 Bool -> Bool -> Bool
|| Bool
isProgressiveImage = (Int
xSampling, Int
ySampling)
| Bool
otherwise = (Int
1, Int
1)
[(JpgUnpackerParameter, Unpacker s)]
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
[(JpgUnpackerParameter, Unpacker s)]
forall a.
a
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [ (JpgUnpackerParameter
{ dcHuffmanTree :: HuffmanPackedTree
dcHuffmanTree = HuffmanPackedTree
dcTree
, acHuffmanTree :: HuffmanPackedTree
acHuffmanTree = HuffmanPackedTree
acTree
, componentIndex :: Int
componentIndex = Int
comp
, restartInterval :: Int
restartInterval = Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
restart
, componentWidth :: Int
componentWidth = Int
xSampling
, componentHeight :: Int
componentHeight = Int
ySampling
, subSampling :: (Int, Int)
subSampling = (Int, Int)
componentSubSampling
, successiveApprox :: (Int, Int)
successiveApprox = (Int
approxLow, Int
approxHigh)
, readerIndex :: Int
readerIndex = Int
blobId
, indiceVector :: Int
indiceVector =
if Int
scanCount Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 then Int
0 else Int
1
, coefficientRange :: (Int, Int)
coefficientRange =
( Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
selectionLow
, Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
selectionHigh )
, blockIndex :: Int
blockIndex = Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
xSampling Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x
, blockMcuX :: Int
blockMcuX = Int
x
, blockMcuY :: Int
blockMcuY = Int
y
}, Int -> (Int, Int) -> Unpacker s
forall s. Int -> (Int, Int) -> Unpacker s
unpackerDecision Int
compCount (Int, Int)
componentSubSampling)
| Int
y <- [Int
0 .. Int
yCount Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
, Int
x <- [Int
0 .. Int
xCount Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1] ]
jpgMachineStep (JpgScans JpgFrameKind
kind JpgFrameHeader
hdr) = (JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall w (m :: * -> *) s r.
(Monoid w, Monad m) =>
(s -> s) -> RWST r w s m ()
modify ((JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
())
-> (JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall a b. (a -> b) -> a -> b
$ \JpgDecoderState
s ->
JpgDecoderState
s { currentFrame = Just hdr
, componentIndexMapping =
[(componentIdentifier comp, ix) | (ix, comp) <- zip [0..] $ jpgComponents hdr]
, isProgressive = case kind of
JpgFrameKind
JpgProgressiveDCTHuffman -> Bool
True
JpgFrameKind
_ -> Bool
False
, maximumHorizontalResolution =
fromIntegral $ maximum horizontalResolutions
, maximumVerticalResolution =
fromIntegral $ maximum verticalResolutions
}
where components :: [JpgComponent]
components = JpgFrameHeader -> [JpgComponent]
jpgComponents JpgFrameHeader
hdr
horizontalResolutions :: [Word8]
horizontalResolutions = (JpgComponent -> Word8) -> [JpgComponent] -> [Word8]
forall a b. (a -> b) -> [a] -> [b]
map JpgComponent -> Word8
horizontalSamplingFactor [JpgComponent]
components
verticalResolutions :: [Word8]
verticalResolutions = (JpgComponent -> Word8) -> [JpgComponent] -> [Word8]
forall a b. (a -> b) -> [a] -> [b]
map JpgComponent -> Word8
verticalSamplingFactor [JpgComponent]
components
jpgMachineStep (JpgIntervalRestart Word16
restart) =
(JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall w (m :: * -> *) s r.
(Monoid w, Monad m) =>
(s -> s) -> RWST r w s m ()
modify ((JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
())
-> (JpgDecoderState -> JpgDecoderState)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall a b. (a -> b) -> a -> b
$ \JpgDecoderState
s -> JpgDecoderState
s { currentRestartInterv = fromIntegral restart }
jpgMachineStep (JpgHuffmanTable [(JpgHuffmanTableSpec, HuffmanPackedTree)]
tables) = ((JpgHuffmanTableSpec, HuffmanPackedTree)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
())
-> [(JpgHuffmanTableSpec, HuffmanPackedTree)]
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (JpgHuffmanTableSpec, HuffmanPackedTree)
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall {w} {m :: * -> *} {r}.
(Monoid w, Monad m) =>
(JpgHuffmanTableSpec, HuffmanPackedTree)
-> RWST r w JpgDecoderState m ()
placeHuffmanTrees [(JpgHuffmanTableSpec, HuffmanPackedTree)]
tables
where placeHuffmanTrees :: (JpgHuffmanTableSpec, HuffmanPackedTree)
-> RWST r w JpgDecoderState m ()
placeHuffmanTrees (JpgHuffmanTableSpec
spec, HuffmanPackedTree
tree) = case JpgHuffmanTableSpec -> DctComponent
huffmanTableClass JpgHuffmanTableSpec
spec of
DctComponent
DcComponent -> (JpgDecoderState -> JpgDecoderState)
-> RWST r w JpgDecoderState m ()
forall w (m :: * -> *) s r.
(Monoid w, Monad m) =>
(s -> s) -> RWST r w s m ()
modify ((JpgDecoderState -> JpgDecoderState)
-> RWST r w JpgDecoderState m ())
-> (JpgDecoderState -> JpgDecoderState)
-> RWST r w JpgDecoderState m ()
forall a b. (a -> b) -> a -> b
$ \JpgDecoderState
s ->
if Int
idx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Vector HuffmanPackedTree -> Int
forall a. Vector a -> Int
V.length (JpgDecoderState -> Vector HuffmanPackedTree
dcDecoderTables JpgDecoderState
s) then JpgDecoderState
s
else
let neu :: Vector HuffmanPackedTree
neu = JpgDecoderState -> Vector HuffmanPackedTree
dcDecoderTables JpgDecoderState
s Vector HuffmanPackedTree
-> [(Int, HuffmanPackedTree)] -> Vector HuffmanPackedTree
forall a. Vector a -> [(Int, a)] -> Vector a
// [(Int
idx, HuffmanPackedTree
tree)] in
JpgDecoderState
s { dcDecoderTables = neu }
where idx :: Int
idx = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Word8 -> Int
forall a b. (a -> b) -> a -> b
$ JpgHuffmanTableSpec -> Word8
huffmanTableDest JpgHuffmanTableSpec
spec
DctComponent
AcComponent -> (JpgDecoderState -> JpgDecoderState)
-> RWST r w JpgDecoderState m ()
forall w (m :: * -> *) s r.
(Monoid w, Monad m) =>
(s -> s) -> RWST r w s m ()
modify ((JpgDecoderState -> JpgDecoderState)
-> RWST r w JpgDecoderState m ())
-> (JpgDecoderState -> JpgDecoderState)
-> RWST r w JpgDecoderState m ()
forall a b. (a -> b) -> a -> b
$ \JpgDecoderState
s ->
if Int
idx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Vector HuffmanPackedTree -> Int
forall a. Vector a -> Int
V.length (JpgDecoderState -> Vector HuffmanPackedTree
acDecoderTables JpgDecoderState
s) then JpgDecoderState
s
else
JpgDecoderState
s { acDecoderTables = acDecoderTables s // [(idx, tree)] }
where idx :: Int
idx = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Word8 -> Int
forall a b. (a -> b) -> a -> b
$ JpgHuffmanTableSpec -> Word8
huffmanTableDest JpgHuffmanTableSpec
spec
jpgMachineStep (JpgQuantTable [JpgQuantTableSpec]
tables) = (JpgQuantTableSpec
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
())
-> [JpgQuantTableSpec]
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ JpgQuantTableSpec
-> RWST
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
Identity
()
forall {w} {m :: * -> *} {r}.
(Monoid w, Monad m) =>
JpgQuantTableSpec -> RWST r w JpgDecoderState m ()
placeQuantizationTables [JpgQuantTableSpec]
tables
where placeQuantizationTables :: JpgQuantTableSpec -> RWST r w JpgDecoderState m ()
placeQuantizationTables JpgQuantTableSpec
table = do
let idx :: Int
idx = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Word8 -> Int
forall a b. (a -> b) -> a -> b
$ JpgQuantTableSpec -> Word8
quantDestination JpgQuantTableSpec
table
tableData :: MacroBlock Int16
tableData = JpgQuantTableSpec -> MacroBlock Int16
quantTable JpgQuantTableSpec
table
(JpgDecoderState -> JpgDecoderState)
-> RWST r w JpgDecoderState m ()
forall w (m :: * -> *) s r.
(Monoid w, Monad m) =>
(s -> s) -> RWST r w s m ()
modify ((JpgDecoderState -> JpgDecoderState)
-> RWST r w JpgDecoderState m ())
-> (JpgDecoderState -> JpgDecoderState)
-> RWST r w JpgDecoderState m ()
forall a b. (a -> b) -> a -> b
$ \JpgDecoderState
s ->
JpgDecoderState
s { quantizationMatrices = quantizationMatrices s // [(idx, tableData)] }
unpackerDecision :: Int -> (Int, Int) -> Unpacker s
unpackerDecision :: forall s. Int -> (Int, Int) -> Unpacker s
unpackerDecision Int
1 (Int
1, Int
1) = Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
forall s.
Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
unpack444Y
unpackerDecision Int
3 (Int
1, Int
1) = Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
forall s.
Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
unpack444Ycbcr
unpackerDecision Int
_ (Int
2, Int
1) = Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
forall s.
Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
unpack421Ycbcr
unpackerDecision Int
compCount (Int
xScalingFactor, Int
yScalingFactor) =
Int
-> Int
-> Int
-> Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
forall s.
Int
-> Int
-> Int
-> Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
unpackMacroBlock Int
compCount Int
xScalingFactor Int
yScalingFactor
decodeImage :: JpgFrameHeader
-> V.Vector (MacroBlock Int16)
-> [([(JpgUnpackerParameter, Unpacker s)], L.ByteString)]
-> MutableImage s PixelYCbCr8
-> ST s (MutableImage s PixelYCbCr8)
decodeImage :: forall s.
JpgFrameHeader
-> Vector (MacroBlock Int16)
-> [([(JpgUnpackerParameter, Unpacker s)], ByteString)]
-> MutableImage s PixelYCbCr8
-> ST s (MutableImage s PixelYCbCr8)
decodeImage JpgFrameHeader
frame Vector (MacroBlock Int16)
quants [([(JpgUnpackerParameter, Unpacker s)], ByteString)]
lst MutableImage s PixelYCbCr8
outImage = do
let compCount :: Int
compCount = [JpgComponent] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([JpgComponent] -> Int) -> [JpgComponent] -> Int
forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> [JpgComponent]
jpgComponents JpgFrameHeader
frame
MutableMacroBlock s Int16
zigZagArray <- ST s (MutableMacroBlock s Int16)
forall a s. (Storable a, Num a) => ST s (MutableMacroBlock s a)
createEmptyMutableMacroBlock
MutableMacroBlock s Int16
dcArray <- Int -> Int16 -> ST s (MVector (PrimState (ST s)) Int16)
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> a -> m (MVector (PrimState m) a)
M.replicate Int
compCount Int16
0 :: ST s (M.STVector s DcCoefficient)
STRef s Int
resetCounter <- Int -> ST s (STRef s Int)
forall a s. a -> ST s (STRef s a)
newSTRef Int
restartIntervalValue
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
-> (([(JpgUnpackerParameter, Unpacker s)], ByteString)
-> ST s BoolState)
-> ST s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [([(JpgUnpackerParameter, Unpacker s)], ByteString)]
lst ((([(JpgUnpackerParameter, Unpacker s)], ByteString)
-> ST s BoolState)
-> ST s ())
-> (([(JpgUnpackerParameter, Unpacker s)], ByteString)
-> ST s BoolState)
-> ST s ()
forall a b. (a -> b) -> a -> b
$ \([(JpgUnpackerParameter, Unpacker s)]
params, ByteString
str) -> do
let componentsInfo :: Vector (JpgUnpackerParameter, Unpacker s)
componentsInfo = [(JpgUnpackerParameter, Unpacker s)]
-> Vector (JpgUnpackerParameter, Unpacker s)
forall a. [a] -> Vector a
V.fromList [(JpgUnpackerParameter, Unpacker s)]
params
compReader :: BoolState
compReader = ByteString -> BoolState
initBoolStateJpg (ByteString -> BoolState)
-> ([ByteString] -> ByteString) -> [ByteString] -> BoolState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
B.concat ([ByteString] -> BoolState) -> [ByteString] -> BoolState
forall a b. (a -> b) -> a -> b
$ ByteString -> [ByteString]
L.toChunks ByteString
str
maxiSubSampW :: Int
maxiSubSampW = [Int] -> Int
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [(Int, Int) -> Int
forall a b. (a, b) -> a
fst ((Int, Int) -> Int) -> (Int, Int) -> Int
forall a b. (a -> b) -> a -> b
$ JpgUnpackerParameter -> (Int, Int)
subSampling JpgUnpackerParameter
c | (JpgUnpackerParameter
c,Unpacker s
_) <- [(JpgUnpackerParameter, Unpacker s)]
params]
maxiSubSampH :: Int
maxiSubSampH = [Int] -> Int
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [(Int, Int) -> Int
forall a b. (a, b) -> b
snd ((Int, Int) -> Int) -> (Int, Int) -> Int
forall a b. (a -> b) -> a -> b
$ JpgUnpackerParameter -> (Int, Int)
subSampling JpgUnpackerParameter
c | (JpgUnpackerParameter
c,Unpacker s
_) <- [(JpgUnpackerParameter, Unpacker s)]
params]
(Int
maxiW, Int
maxiH) =
if [(JpgUnpackerParameter, Unpacker s)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(JpgUnpackerParameter, Unpacker s)]
params Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 then
([Int] -> Int
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [JpgUnpackerParameter -> Int
componentWidth JpgUnpackerParameter
c | (JpgUnpackerParameter
c,Unpacker s
_) <- [(JpgUnpackerParameter, Unpacker s)]
params],
[Int] -> Int
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [JpgUnpackerParameter -> Int
componentHeight JpgUnpackerParameter
c | (JpgUnpackerParameter
c,Unpacker s
_) <- [(JpgUnpackerParameter, Unpacker s)]
params])
else
(Int
maxiSubSampW, Int
maxiSubSampH)
imageBlockWidth :: Int
imageBlockWidth = Int -> Int
toBlockSize Int
imgWidth
imageBlockHeight :: Int
imageBlockHeight = Int -> Int
toBlockSize Int
imgHeight
imageMcuWidth :: Int
imageMcuWidth = (Int
imageBlockWidth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
maxiW Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
maxiW
imageMcuHeight :: Int
imageMcuHeight = (Int
imageBlockHeight Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
maxiH Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
maxiH
BoolState -> BoolReader s () -> ST s BoolState
forall s a. BoolState -> BoolReader s a -> ST s BoolState
execBoolReader BoolState
compReader (BoolReader s () -> ST s BoolState)
-> BoolReader s () -> ST s BoolState
forall a b. (a -> b) -> a -> b
$ Int -> Int -> (Int -> Int -> BoolReader s ()) -> BoolReader s ()
forall (m :: * -> *).
Monad m =>
Int -> Int -> (Int -> Int -> m ()) -> m ()
rasterMap Int
imageMcuWidth Int
imageMcuHeight ((Int -> Int -> BoolReader s ()) -> BoolReader s ())
-> (Int -> Int -> BoolReader s ()) -> BoolReader s ()
forall a b. (a -> b) -> a -> b
$ \Int
x Int
y -> do
Int
resetLeft <- ST s Int -> StateT BoolState (ST s) Int
forall (m :: * -> *) a. Monad m => m a -> StateT BoolState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s Int -> StateT BoolState (ST s) Int)
-> ST s Int -> StateT BoolState (ST s) Int
forall a b. (a -> b) -> a -> b
$ STRef s Int -> ST s Int
forall s a. STRef s a -> ST s a
readSTRef STRef s Int
resetCounter
if Int
resetLeft Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then do
ST s () -> BoolReader s ()
forall (m :: * -> *) a. Monad m => m a -> StateT BoolState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s () -> BoolReader s ()) -> ST s () -> BoolReader s ()
forall a b. (a -> b) -> a -> b
$ MVector (PrimState (ST s)) Int16 -> Int16 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> a -> m ()
M.set MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
dcArray Int16
0
BoolReader s ()
forall s. BoolReader s ()
byteAlignJpg
Int32
_restartCode <- BoolReader s Int32
forall s. BoolReader s Int32
decodeRestartInterval
ST s () -> BoolReader s ()
forall (m :: * -> *) a. Monad m => m a -> StateT BoolState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s () -> BoolReader s ()) -> ST s () -> BoolReader s ()
forall a b. (a -> b) -> a -> b
$ STRef s Int
resetCounter STRef s Int -> Int -> ST s ()
forall s a. STRef s a -> a -> ST s ()
`writeSTRef` (Int
restartIntervalValue Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
else
ST s () -> BoolReader s ()
forall (m :: * -> *) a. Monad m => m a -> StateT BoolState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s () -> BoolReader s ()) -> ST s () -> BoolReader s ()
forall a b. (a -> b) -> a -> b
$ STRef s Int
resetCounter STRef s Int -> Int -> ST s ()
forall s a. STRef s a -> a -> ST s ()
`writeSTRef` (Int
resetLeft Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
Vector (JpgUnpackerParameter, Unpacker s)
-> ((JpgUnpackerParameter, Unpacker s) -> BoolReader s ())
-> BoolReader s ()
forall (m :: * -> *) a b. Monad m => Vector a -> (a -> m b) -> m ()
V.forM_ Vector (JpgUnpackerParameter, Unpacker s)
componentsInfo (((JpgUnpackerParameter, Unpacker s) -> BoolReader s ())
-> BoolReader s ())
-> ((JpgUnpackerParameter, Unpacker s) -> BoolReader s ())
-> BoolReader s ()
forall a b. (a -> b) -> a -> b
$ \(JpgUnpackerParameter
comp, Unpacker s
unpack) -> do
let compIdx :: Int
compIdx = JpgUnpackerParameter -> Int
componentIndex JpgUnpackerParameter
comp
dcTree :: HuffmanPackedTree
dcTree = JpgUnpackerParameter -> HuffmanPackedTree
dcHuffmanTree JpgUnpackerParameter
comp
acTree :: HuffmanPackedTree
acTree = JpgUnpackerParameter -> HuffmanPackedTree
acHuffmanTree JpgUnpackerParameter
comp
quantId :: Int
quantId = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> (JpgComponent -> Word8) -> JpgComponent -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JpgComponent -> Word8
quantizationTableDest
(JpgComponent -> Int) -> JpgComponent -> Int
forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> [JpgComponent]
jpgComponents JpgFrameHeader
frame [JpgComponent] -> Int -> JpgComponent
forall a. HasCallStack => [a] -> Int -> a
!! Int
compIdx
qTable :: MacroBlock Int16
qTable = Vector (MacroBlock Int16)
quants Vector (MacroBlock Int16) -> Int -> MacroBlock Int16
forall a. Vector a -> Int -> a
V.! Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
3 Int
quantId
xd :: Int
xd = JpgUnpackerParameter -> Int
blockMcuX JpgUnpackerParameter
comp
yd :: Int
yd = JpgUnpackerParameter -> Int
blockMcuY JpgUnpackerParameter
comp
(Int
subX, Int
subY) = JpgUnpackerParameter -> (Int, Int)
subSampling JpgUnpackerParameter
comp
Int16
dc <- ST s Int16 -> StateT BoolState (ST s) Int16
forall (m :: * -> *) a. Monad m => m a -> StateT BoolState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s Int16 -> StateT BoolState (ST s) Int16)
-> ST s Int16 -> StateT BoolState (ST s) Int16
forall a b. (a -> b) -> a -> b
$ MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
dcArray MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` Int
compIdx
(Int16
dcCoeff, MutableMacroBlock s Int16
block) <-
HuffmanPackedTree
-> HuffmanPackedTree
-> MacroBlock Int16
-> MutableMacroBlock s Int16
-> Int16
-> BoolReader s (Int16, MutableMacroBlock s Int16)
forall s.
HuffmanPackedTree
-> HuffmanPackedTree
-> MacroBlock Int16
-> MutableMacroBlock s Int16
-> Int16
-> BoolReader s (Int16, MutableMacroBlock s Int16)
decompressMacroBlock HuffmanPackedTree
dcTree HuffmanPackedTree
acTree MacroBlock Int16
qTable MutableMacroBlock s Int16
zigZagArray (Int16 -> BoolReader s (Int16, MutableMacroBlock s Int16))
-> Int16 -> BoolReader s (Int16, MutableMacroBlock s Int16)
forall a b. (a -> b) -> a -> b
$ Int16 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int16
dc
ST s () -> BoolReader s ()
forall (m :: * -> *) a. Monad m => m a -> StateT BoolState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s () -> BoolReader s ()) -> ST s () -> BoolReader s ()
forall a b. (a -> b) -> a -> b
$ (MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
dcArray MVector (PrimState (ST s)) Int16 -> Int -> Int16 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` Int
compIdx) Int16
dcCoeff
let verticalLimited :: Bool
verticalLimited = Int
y Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
imageMcuHeight Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
if (Int
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
imageMcuWidth Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Bool -> Bool -> Bool
|| Bool
verticalLimited then
ST s () -> BoolReader s ()
forall (m :: * -> *) a. Monad m => m a -> StateT BoolState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s () -> BoolReader s ()) -> ST s () -> BoolReader s ()
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> Unpacker s
forall s.
Int
-> Int
-> Int
-> Int
-> Int
-> Int
-> MutableImage s PixelYCbCr8
-> MutableMacroBlock s Int16
-> ST s ()
unpackMacroBlock Int
imgComponentCount
Int
subX Int
subY Int
compIdx
(Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
maxiW Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
xd) (Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
maxiH Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
yd) MutableImage s PixelYCbCr8
outImage MutableMacroBlock s Int16
block
else
ST s () -> BoolReader s ()
forall (m :: * -> *) a. Monad m => m a -> StateT BoolState m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s () -> BoolReader s ()) -> ST s () -> BoolReader s ()
forall a b. (a -> b) -> a -> b
$ Unpacker s
unpack Int
compIdx (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
maxiW Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
xd) (Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
maxiH Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
yd) MutableImage s PixelYCbCr8
outImage MutableMacroBlock s Int16
block
MutableImage s PixelYCbCr8 -> ST s (MutableImage s PixelYCbCr8)
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return MutableImage s PixelYCbCr8
outImage
where imgComponentCount :: Int
imgComponentCount = [JpgComponent] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([JpgComponent] -> Int) -> [JpgComponent] -> Int
forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> [JpgComponent]
jpgComponents JpgFrameHeader
frame
imgWidth :: Int
imgWidth = Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int) -> Word16 -> Int
forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> Word16
jpgWidth JpgFrameHeader
frame
imgHeight :: Int
imgHeight = Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int) -> Word16 -> Int
forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> Word16
jpgHeight JpgFrameHeader
frame
restartIntervalValue :: Int
restartIntervalValue = case [([(JpgUnpackerParameter, Unpacker s)], ByteString)]
lst of
((JpgUnpackerParameter
p,Unpacker s
_):[(JpgUnpackerParameter, Unpacker s)]
_,ByteString
_): [([(JpgUnpackerParameter, Unpacker s)], ByteString)]
_ -> JpgUnpackerParameter -> Int
restartInterval JpgUnpackerParameter
p
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
_ -> -Int
1
gatherImageKind :: [JpgFrame] -> Maybe JpgImageKind
gatherImageKind :: [JpgFrame] -> Maybe JpgImageKind
gatherImageKind [JpgFrame]
lst = case [JpgFrameKind
k | JpgScans JpgFrameKind
k JpgFrameHeader
_ <- [JpgFrame]
lst, JpgFrameKind -> Bool
isDctSpecifier JpgFrameKind
k] of
[JpgFrameKind
JpgBaselineDCTHuffman] -> JpgImageKind -> Maybe JpgImageKind
forall a. a -> Maybe a
Just JpgImageKind
BaseLineDCT
[JpgFrameKind
JpgProgressiveDCTHuffman] -> JpgImageKind -> Maybe JpgImageKind
forall a. a -> Maybe a
Just JpgImageKind
ProgressiveDCT
[JpgFrameKind
JpgExtendedSequentialDCTHuffman] -> JpgImageKind -> Maybe JpgImageKind
forall a. a -> Maybe a
Just JpgImageKind
BaseLineDCT
[JpgFrameKind]
_ -> Maybe JpgImageKind
forall a. Maybe a
Nothing
where isDctSpecifier :: JpgFrameKind -> Bool
isDctSpecifier JpgFrameKind
JpgProgressiveDCTHuffman = Bool
True
isDctSpecifier JpgFrameKind
JpgBaselineDCTHuffman = Bool
True
isDctSpecifier JpgFrameKind
JpgExtendedSequentialDCTHuffman = Bool
True
isDctSpecifier JpgFrameKind
_ = Bool
False
gatherScanInfo :: JpgImage -> (JpgFrameKind, JpgFrameHeader)
gatherScanInfo :: JpgImage -> (JpgFrameKind, JpgFrameHeader)
gatherScanInfo JpgImage
img = [(JpgFrameKind, JpgFrameHeader)] -> (JpgFrameKind, JpgFrameHeader)
forall a. HasCallStack => [a] -> a
head [(JpgFrameKind
a, JpgFrameHeader
b) | JpgScans JpgFrameKind
a JpgFrameHeader
b <- JpgImage -> [JpgFrame]
jpgFrame JpgImage
img]
dynamicOfColorSpace :: Maybe JpgColorSpace -> Int -> Int -> VS.Vector Word8
-> Either String DynamicImage
dynamicOfColorSpace :: Maybe JpgColorSpace
-> Int -> Int -> Vector Word8 -> Either String DynamicImage
dynamicOfColorSpace Maybe JpgColorSpace
Nothing Int
_ Int
_ Vector Word8
_ = String -> Either String DynamicImage
forall a b. a -> Either a b
Left String
"Unknown color space"
dynamicOfColorSpace (Just JpgColorSpace
color) Int
w Int
h Vector Word8
imgData = case JpgColorSpace
color of
JpgColorSpace
JpgColorSpaceCMYK -> DynamicImage -> Either String DynamicImage
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return (DynamicImage -> Either String DynamicImage)
-> (Image PixelCMYK8 -> DynamicImage)
-> Image PixelCMYK8
-> Either String DynamicImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Image PixelCMYK8 -> DynamicImage
ImageCMYK8 (Image PixelCMYK8 -> Either String DynamicImage)
-> Image PixelCMYK8 -> Either String DynamicImage
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Vector (PixelBaseComponent PixelCMYK8)
-> Image PixelCMYK8
forall a. Int -> Int -> Vector (PixelBaseComponent a) -> Image a
Image Int
w Int
h Vector Word8
Vector (PixelBaseComponent PixelCMYK8)
imgData
JpgColorSpace
JpgColorSpaceYCCK ->
let ymg :: Image PixelYCbCrK8
ymg = Int
-> Int
-> Vector (PixelBaseComponent PixelYCbCrK8)
-> Image PixelYCbCrK8
forall a. Int -> Int -> Vector (PixelBaseComponent a) -> Image a
Image Int
w Int
h (Vector (PixelBaseComponent PixelYCbCrK8) -> Image PixelYCbCrK8)
-> Vector (PixelBaseComponent PixelYCbCrK8) -> Image PixelYCbCrK8
forall a b. (a -> b) -> a -> b
$ (Word8 -> Word8) -> Vector Word8 -> Vector Word8
forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
VS.map (Word8
255Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
-) Vector Word8
imgData :: Image PixelYCbCrK8 in
DynamicImage -> Either String DynamicImage
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return (DynamicImage -> Either String DynamicImage)
-> (Image PixelCMYK8 -> DynamicImage)
-> Image PixelCMYK8
-> Either String DynamicImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Image PixelCMYK8 -> DynamicImage
ImageCMYK8 (Image PixelCMYK8 -> Either String DynamicImage)
-> Image PixelCMYK8 -> Either String DynamicImage
forall a b. (a -> b) -> a -> b
$ Image PixelYCbCrK8 -> Image PixelCMYK8
forall a b. ColorSpaceConvertible a b => Image a -> Image b
convertImage Image PixelYCbCrK8
ymg
JpgColorSpace
JpgColorSpaceYCbCr -> DynamicImage -> Either String DynamicImage
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return (DynamicImage -> Either String DynamicImage)
-> (Image PixelYCbCr8 -> DynamicImage)
-> Image PixelYCbCr8
-> Either String DynamicImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Image PixelYCbCr8 -> DynamicImage
ImageYCbCr8 (Image PixelYCbCr8 -> Either String DynamicImage)
-> Image PixelYCbCr8 -> Either String DynamicImage
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> Vector (PixelBaseComponent PixelYCbCr8)
-> Image PixelYCbCr8
forall a. Int -> Int -> Vector (PixelBaseComponent a) -> Image a
Image Int
w Int
h Vector Word8
Vector (PixelBaseComponent PixelYCbCr8)
imgData
JpgColorSpace
JpgColorSpaceRGB -> DynamicImage -> Either String DynamicImage
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return (DynamicImage -> Either String DynamicImage)
-> (Image PixelRGB8 -> DynamicImage)
-> Image PixelRGB8
-> Either String DynamicImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Image PixelRGB8 -> DynamicImage
ImageRGB8 (Image PixelRGB8 -> Either String DynamicImage)
-> Image PixelRGB8 -> Either String DynamicImage
forall a b. (a -> b) -> a -> b
$ Int
-> Int -> Vector (PixelBaseComponent PixelRGB8) -> Image PixelRGB8
forall a. Int -> Int -> Vector (PixelBaseComponent a) -> Image a
Image Int
w Int
h Vector Word8
Vector (PixelBaseComponent PixelRGB8)
imgData
JpgColorSpace
JpgColorSpaceYA -> DynamicImage -> Either String DynamicImage
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return (DynamicImage -> Either String DynamicImage)
-> (Image PixelYA8 -> DynamicImage)
-> Image PixelYA8
-> Either String DynamicImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Image PixelYA8 -> DynamicImage
ImageYA8 (Image PixelYA8 -> Either String DynamicImage)
-> Image PixelYA8 -> Either String DynamicImage
forall a b. (a -> b) -> a -> b
$ Int
-> Int -> Vector (PixelBaseComponent PixelYA8) -> Image PixelYA8
forall a. Int -> Int -> Vector (PixelBaseComponent a) -> Image a
Image Int
w Int
h Vector Word8
Vector (PixelBaseComponent PixelYA8)
imgData
JpgColorSpace
JpgColorSpaceY -> DynamicImage -> Either String DynamicImage
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return (DynamicImage -> Either String DynamicImage)
-> (Image Word8 -> DynamicImage)
-> Image Word8
-> Either String DynamicImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Image Word8 -> DynamicImage
ImageY8 (Image Word8 -> Either String DynamicImage)
-> Image Word8 -> Either String DynamicImage
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Vector (PixelBaseComponent Word8) -> Image Word8
forall a. Int -> Int -> Vector (PixelBaseComponent a) -> Image a
Image Int
w Int
h Vector Word8
Vector (PixelBaseComponent Word8)
imgData
JpgColorSpace
colorSpace -> String -> Either String DynamicImage
forall a b. a -> Either a b
Left (String -> Either String DynamicImage)
-> String -> Either String DynamicImage
forall a b. (a -> b) -> a -> b
$ String
"Wrong color space : " String -> String -> String
forall a. [a] -> [a] -> [a]
++ JpgColorSpace -> String
forall a. Show a => a -> String
show JpgColorSpace
colorSpace
colorSpaceOfAdobe :: Int -> JpgAdobeApp14 -> Maybe JpgColorSpace
colorSpaceOfAdobe :: Int -> JpgAdobeApp14 -> Maybe JpgColorSpace
colorSpaceOfAdobe Int
compCount JpgAdobeApp14
app = case (Int
compCount, JpgAdobeApp14 -> AdobeTransform
_adobeTransform JpgAdobeApp14
app) of
(Int
3, AdobeTransform
AdobeYCbCr) -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceYCbCr
(Int
1, AdobeTransform
AdobeUnknown) -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceY
(Int
3, AdobeTransform
AdobeUnknown) -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceRGB
(Int
4, AdobeTransform
AdobeYCck) -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceYCCK
(Int, AdobeTransform)
_ -> Maybe JpgColorSpace
forall a. Maybe a
Nothing
colorSpaceOfState :: JpgDecoderState -> Maybe JpgColorSpace
colorSpaceOfState :: JpgDecoderState -> Maybe JpgColorSpace
colorSpaceOfState JpgDecoderState
st = do
JpgFrameHeader
hdr <- JpgDecoderState -> Maybe JpgFrameHeader
currentFrame JpgDecoderState
st
let compStr :: String
compStr = [Int -> Char
forall a. Enum a => Int -> a
toEnum (Int -> Char) -> (Word8 -> Int) -> Word8 -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a. Enum a => a -> Int
fromEnum (Word8 -> Char) -> Word8 -> Char
forall a b. (a -> b) -> a -> b
$ JpgComponent -> Word8
componentIdentifier JpgComponent
comp
| JpgComponent
comp <- JpgFrameHeader -> [JpgComponent]
jpgComponents JpgFrameHeader
hdr]
app14 :: Maybe JpgColorSpace
app14 = do
JpgAdobeApp14
marker <- JpgDecoderState -> Maybe JpgAdobeApp14
app14Marker JpgDecoderState
st
Int -> JpgAdobeApp14 -> Maybe JpgColorSpace
colorSpaceOfAdobe (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
compStr) JpgAdobeApp14
marker
Maybe JpgColorSpace
app14 Maybe JpgColorSpace -> Maybe JpgColorSpace -> Maybe JpgColorSpace
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> Maybe JpgColorSpace
colorSpaceOfComponentStr String
compStr
colorSpaceOfComponentStr :: String -> Maybe JpgColorSpace
colorSpaceOfComponentStr :: String -> Maybe JpgColorSpace
colorSpaceOfComponentStr String
s = case String
s of
[Char
_] -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceY
[Char
_,Char
_] -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceYA
String
"\0\1\2" -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceYCbCr
String
"\1\2\3" -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceYCbCr
String
"RGB" -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceRGB
String
"YCc" -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceYCC
[Char
_,Char
_,Char
_] -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceYCbCr
String
"RGBA" -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceRGBA
String
"YCcA" -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceYCCA
String
"CMYK" -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceCMYK
String
"YCcK" -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceYCCK
[Char
_,Char
_,Char
_,Char
_] -> JpgColorSpace -> Maybe JpgColorSpace
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JpgColorSpace
JpgColorSpaceCMYK
String
_ -> Maybe JpgColorSpace
forall a. Maybe a
Nothing
decodeJpeg :: B.ByteString -> Either String DynamicImage
decodeJpeg :: ByteString -> Either String DynamicImage
decodeJpeg = ((DynamicImage, Metadatas) -> DynamicImage)
-> Either String (DynamicImage, Metadatas)
-> Either String DynamicImage
forall a b. (a -> b) -> Either String a -> Either String b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (DynamicImage, Metadatas) -> DynamicImage
forall a b. (a, b) -> a
fst (Either String (DynamicImage, Metadatas)
-> Either String DynamicImage)
-> (ByteString -> Either String (DynamicImage, Metadatas))
-> ByteString
-> Either String DynamicImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either String (DynamicImage, Metadatas)
decodeJpegWithMetadata
decodeJpegWithMetadata :: B.ByteString -> Either String (DynamicImage, Metadatas)
decodeJpegWithMetadata :: ByteString -> Either String (DynamicImage, Metadatas)
decodeJpegWithMetadata ByteString
file = case Get JpgImage -> ByteString -> Either String JpgImage
forall a. Get a -> ByteString -> Either String a
runGetStrict Get JpgImage
forall t. Binary t => Get t
get ByteString
file of
Left String
err -> String -> Either String (DynamicImage, Metadatas)
forall a b. a -> Either a b
Left String
err
Right JpgImage
img -> case Maybe JpgImageKind
imgKind of
Just JpgImageKind
BaseLineDCT ->
let (JpgDecoderState
st, Vector Word8
arr) = (JpgDecoderState, Vector Word8)
decodeBaseline
jfifMeta :: Metadatas
jfifMeta = (JpgJFIFApp0 -> Metadatas) -> Maybe JpgJFIFApp0 -> Metadatas
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap JpgJFIFApp0 -> Metadatas
extractMetadatas (Maybe JpgJFIFApp0 -> Metadatas) -> Maybe JpgJFIFApp0 -> Metadatas
forall a b. (a -> b) -> a -> b
$ JpgDecoderState -> Maybe JpgJFIFApp0
app0JFifMarker JpgDecoderState
st
exifMeta :: Metadatas
exifMeta = ([ImageFileDirectory] -> Metadatas)
-> Maybe [ImageFileDirectory] -> Metadatas
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap [ImageFileDirectory] -> Metadatas
extractTiffMetadata (Maybe [ImageFileDirectory] -> Metadatas)
-> Maybe [ImageFileDirectory] -> Metadatas
forall a b. (a -> b) -> a -> b
$ JpgDecoderState -> Maybe [ImageFileDirectory]
app1ExifMarker JpgDecoderState
st
meta :: Metadatas
meta = Metadatas
jfifMeta Metadatas -> Metadatas -> Metadatas
forall a. Semigroup a => a -> a -> a
<> Metadatas
exifMeta Metadatas -> Metadatas -> Metadatas
forall a. Semigroup a => a -> a -> a
<> Metadatas
sizeMeta
in
(, Metadatas
meta) (DynamicImage -> (DynamicImage, Metadatas))
-> Either String DynamicImage
-> Either String (DynamicImage, Metadatas)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Maybe JpgColorSpace
-> Int -> Int -> Vector Word8 -> Either String DynamicImage
dynamicOfColorSpace (JpgDecoderState -> Maybe JpgColorSpace
colorSpaceOfState JpgDecoderState
st) Int
imgWidth Int
imgHeight Vector Word8
arr
Just JpgImageKind
ProgressiveDCT ->
let (JpgDecoderState
st, Vector Word8
arr) = (JpgDecoderState, Vector Word8)
decodeProgressive
jfifMeta :: Metadatas
jfifMeta = (JpgJFIFApp0 -> Metadatas) -> Maybe JpgJFIFApp0 -> Metadatas
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap JpgJFIFApp0 -> Metadatas
extractMetadatas (Maybe JpgJFIFApp0 -> Metadatas) -> Maybe JpgJFIFApp0 -> Metadatas
forall a b. (a -> b) -> a -> b
$ JpgDecoderState -> Maybe JpgJFIFApp0
app0JFifMarker JpgDecoderState
st
exifMeta :: Metadatas
exifMeta = ([ImageFileDirectory] -> Metadatas)
-> Maybe [ImageFileDirectory] -> Metadatas
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap [ImageFileDirectory] -> Metadatas
extractTiffMetadata (Maybe [ImageFileDirectory] -> Metadatas)
-> Maybe [ImageFileDirectory] -> Metadatas
forall a b. (a -> b) -> a -> b
$ JpgDecoderState -> Maybe [ImageFileDirectory]
app1ExifMarker JpgDecoderState
st
meta :: Metadatas
meta = Metadatas
jfifMeta Metadatas -> Metadatas -> Metadatas
forall a. Semigroup a => a -> a -> a
<> Metadatas
exifMeta Metadatas -> Metadatas -> Metadatas
forall a. Semigroup a => a -> a -> a
<> Metadatas
sizeMeta
in
(, Metadatas
meta) (DynamicImage -> (DynamicImage, Metadatas))
-> Either String DynamicImage
-> Either String (DynamicImage, Metadatas)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Maybe JpgColorSpace
-> Int -> Int -> Vector Word8 -> Either String DynamicImage
dynamicOfColorSpace (JpgDecoderState -> Maybe JpgColorSpace
colorSpaceOfState JpgDecoderState
st) Int
imgWidth Int
imgHeight Vector Word8
arr
Maybe JpgImageKind
_ -> String -> Either String (DynamicImage, Metadatas)
forall a b. a -> Either a b
Left String
"Unknown JPG kind"
where
compCount :: Int
compCount = [JpgComponent] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([JpgComponent] -> Int) -> [JpgComponent] -> Int
forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> [JpgComponent]
jpgComponents JpgFrameHeader
scanInfo
(JpgFrameKind
_,JpgFrameHeader
scanInfo) = JpgImage -> (JpgFrameKind, JpgFrameHeader)
gatherScanInfo JpgImage
img
imgKind :: Maybe JpgImageKind
imgKind = [JpgFrame] -> Maybe JpgImageKind
gatherImageKind ([JpgFrame] -> Maybe JpgImageKind)
-> [JpgFrame] -> Maybe JpgImageKind
forall a b. (a -> b) -> a -> b
$ JpgImage -> [JpgFrame]
jpgFrame JpgImage
img
imgWidth :: Int
imgWidth = Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int) -> Word16 -> Int
forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> Word16
jpgWidth JpgFrameHeader
scanInfo
imgHeight :: Int
imgHeight = Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int) -> Word16 -> Int
forall a b. (a -> b) -> a -> b
$ JpgFrameHeader -> Word16
jpgHeight JpgFrameHeader
scanInfo
sizeMeta :: Metadatas
sizeMeta = SourceFormat -> Int -> Int -> Metadatas
forall nSize.
Integral nSize =>
SourceFormat -> nSize -> nSize -> Metadatas
basicMetadata SourceFormat
SourceJpeg Int
imgWidth Int
imgHeight
imageSize :: Int
imageSize = Int
imgWidth Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
imgHeight Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
compCount
decodeProgressive :: (JpgDecoderState, Vector Word8)
decodeProgressive = (forall s. ST s (JpgDecoderState, Vector Word8))
-> (JpgDecoderState, Vector Word8)
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (JpgDecoderState, Vector Word8))
-> (JpgDecoderState, Vector Word8))
-> (forall s. ST s (JpgDecoderState, Vector Word8))
-> (JpgDecoderState, Vector Word8)
forall a b. (a -> b) -> a -> b
$ do
let (JpgDecoderState
st, [([(JpgUnpackerParameter, Unpacker Any)], ByteString)]
wrotten) =
RWS
()
[([(JpgUnpackerParameter, Unpacker Any)], ByteString)]
JpgDecoderState
()
-> ()
-> JpgDecoderState
-> (JpgDecoderState,
[([(JpgUnpackerParameter, Unpacker Any)], ByteString)])
forall r w s a. RWS r w s a -> r -> s -> (s, w)
execRWS ((JpgFrame
-> RWS
()
[([(JpgUnpackerParameter, Unpacker Any)], ByteString)]
JpgDecoderState
())
-> [JpgFrame]
-> RWS
()
[([(JpgUnpackerParameter, Unpacker Any)], ByteString)]
JpgDecoderState
()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ JpgFrame
-> RWS
()
[([(JpgUnpackerParameter, Unpacker Any)], ByteString)]
JpgDecoderState
()
forall s. JpgFrame -> JpgScripter s ()
jpgMachineStep (JpgImage -> [JpgFrame]
jpgFrame JpgImage
img)) () JpgDecoderState
emptyDecoderState
Just JpgFrameHeader
fHdr = JpgDecoderState -> Maybe JpgFrameHeader
currentFrame JpgDecoderState
st
MutableImage s PixelYCbCr8
fimg <-
(Int, Int)
-> JpgFrameHeader
-> Vector (MacroBlock Int16)
-> [([(JpgUnpackerParameter, Unpacker Any)], ByteString)]
-> ST s (MutableImage s PixelYCbCr8)
forall a s.
(Int, Int)
-> JpgFrameHeader
-> Vector (MacroBlock Int16)
-> [([(JpgUnpackerParameter, a)], ByteString)]
-> ST s (MutableImage s PixelYCbCr8)
progressiveUnpack
(JpgDecoderState -> Int
maximumHorizontalResolution JpgDecoderState
st, JpgDecoderState -> Int
maximumVerticalResolution JpgDecoderState
st)
JpgFrameHeader
fHdr
(JpgDecoderState -> Vector (MacroBlock Int16)
quantizationMatrices JpgDecoderState
st)
[([(JpgUnpackerParameter, Unpacker Any)], ByteString)]
wrotten
Image PixelYCbCr8
frozen <- MutableImage (PrimState (ST s)) PixelYCbCr8
-> ST s (Image PixelYCbCr8)
forall a (m :: * -> *).
(Storable (PixelBaseComponent a), PrimMonad m) =>
MutableImage (PrimState m) a -> m (Image a)
unsafeFreezeImage MutableImage s PixelYCbCr8
MutableImage (PrimState (ST s)) PixelYCbCr8
fimg
(JpgDecoderState, Vector Word8)
-> ST s (JpgDecoderState, Vector Word8)
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return (JpgDecoderState
st, Image PixelYCbCr8 -> Vector (PixelBaseComponent PixelYCbCr8)
forall a. Image a -> Vector (PixelBaseComponent a)
imageData Image PixelYCbCr8
frozen)
decodeBaseline :: (JpgDecoderState, Vector Word8)
decodeBaseline = (forall s. ST s (JpgDecoderState, Vector Word8))
-> (JpgDecoderState, Vector Word8)
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (JpgDecoderState, Vector Word8))
-> (JpgDecoderState, Vector Word8))
-> (forall s. ST s (JpgDecoderState, Vector Word8))
-> (JpgDecoderState, Vector Word8)
forall a b. (a -> b) -> a -> b
$ do
let (JpgDecoderState
st, [([(JpgUnpackerParameter, Unpacker s)], ByteString)]
wrotten) =
RWS
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
()
-> ()
-> JpgDecoderState
-> (JpgDecoderState,
[([(JpgUnpackerParameter, Unpacker s)], ByteString)])
forall r w s a. RWS r w s a -> r -> s -> (s, w)
execRWS ((JpgFrame
-> RWS
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
())
-> [JpgFrame]
-> RWS
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ JpgFrame
-> RWS
()
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
JpgDecoderState
()
forall s. JpgFrame -> JpgScripter s ()
jpgMachineStep (JpgImage -> [JpgFrame]
jpgFrame JpgImage
img)) () JpgDecoderState
emptyDecoderState
Just JpgFrameHeader
fHdr = JpgDecoderState -> Maybe JpgFrameHeader
currentFrame JpgDecoderState
st
MVector s Word8
resultImage <- Int -> ST s (MVector (PrimState (ST s)) Word8)
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> m (MVector (PrimState m) a)
M.new Int
imageSize
let wrapped :: MutableImage s PixelYCbCr8
wrapped = Int
-> Int
-> STVector s (PixelBaseComponent PixelYCbCr8)
-> MutableImage s PixelYCbCr8
forall s a.
Int -> Int -> STVector s (PixelBaseComponent a) -> MutableImage s a
MutableImage Int
imgWidth Int
imgHeight MVector s Word8
STVector s (PixelBaseComponent PixelYCbCr8)
resultImage
MutableImage s PixelYCbCr8
fImg <- JpgFrameHeader
-> Vector (MacroBlock Int16)
-> [([(JpgUnpackerParameter, Unpacker s)], ByteString)]
-> MutableImage s PixelYCbCr8
-> ST s (MutableImage s PixelYCbCr8)
forall s.
JpgFrameHeader
-> Vector (MacroBlock Int16)
-> [([(JpgUnpackerParameter, Unpacker s)], ByteString)]
-> MutableImage s PixelYCbCr8
-> ST s (MutableImage s PixelYCbCr8)
decodeImage
JpgFrameHeader
fHdr
(JpgDecoderState -> Vector (MacroBlock Int16)
quantizationMatrices JpgDecoderState
st)
[([(JpgUnpackerParameter, Unpacker s)], ByteString)]
wrotten
MutableImage s PixelYCbCr8
wrapped
Image PixelYCbCr8
frozen <- MutableImage (PrimState (ST s)) PixelYCbCr8
-> ST s (Image PixelYCbCr8)
forall a (m :: * -> *).
(Storable (PixelBaseComponent a), PrimMonad m) =>
MutableImage (PrimState m) a -> m (Image a)
unsafeFreezeImage MutableImage s PixelYCbCr8
MutableImage (PrimState (ST s)) PixelYCbCr8
fImg
(JpgDecoderState, Vector Word8)
-> ST s (JpgDecoderState, Vector Word8)
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return (JpgDecoderState
st, Image PixelYCbCr8 -> Vector (PixelBaseComponent PixelYCbCr8)
forall a. Image a -> Vector (PixelBaseComponent a)
imageData Image PixelYCbCr8
frozen)
extractBlock :: forall s px. (PixelBaseComponent px ~ Word8)
=> Image px
-> MutableMacroBlock s Int16
-> Int
-> Int
-> Int
-> Int
-> Int
-> Int
-> ST s (MutableMacroBlock s Int16)
(Image { imageWidth :: forall a. Image a -> Int
imageWidth = Int
w, imageHeight :: forall a. Image a -> Int
imageHeight = Int
h, imageData :: forall a. Image a -> Vector (PixelBaseComponent a)
imageData = Vector (PixelBaseComponent px)
src })
MutableMacroBlock s Int16
block Int
1 Int
1 Int
sampCount Int
plane Int
bx Int
by | (Int
bx Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
w Bool -> Bool -> Bool
&& (Int
by Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
8) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
h = do
let baseReadIdx :: Int
baseReadIdx = (Int
by Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
w) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
bx Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize
[ST s ()] -> ST s ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ [(MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> Int16 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x)) Int16
val
| Int
y <- [Int
0 .. Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
, let blockReadIdx :: Int
blockReadIdx = Int
baseReadIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
w
, Int
x <- [Int
0 .. Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
, let val :: Int16
val = Word8 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int16) -> Word8 -> Int16
forall a b. (a -> b) -> a -> b
$ Vector Word8
Vector (PixelBaseComponent px)
src Vector Word8 -> Int -> Word8
forall a. Storable a => Vector a -> Int -> a
`VS.unsafeIndex` ((Int
blockReadIdx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sampCount Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
plane)
]
MutableMacroBlock s Int16 -> ST s (MutableMacroBlock s Int16)
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return MutableMacroBlock s Int16
block
extractBlock (Image { imageWidth :: forall a. Image a -> Int
imageWidth = Int
w, imageHeight :: forall a. Image a -> Int
imageHeight = Int
h, imageData :: forall a. Image a -> Vector (PixelBaseComponent a)
imageData = Vector (PixelBaseComponent px)
src })
MutableMacroBlock s Int16
block Int
sampWidth Int
sampHeight Int
sampCount Int
plane Int
bx Int
by = do
let accessPixel :: Int -> Int -> Word8
accessPixel Int
x Int
y | Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
w Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
h = let idx :: Int
idx = (Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sampCount Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
plane in Vector Word8
Vector (PixelBaseComponent px)
src Vector Word8 -> Int -> Word8
forall a. Storable a => Vector a -> Int -> a
`VS.unsafeIndex` Int
idx
| Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
w = Int -> Int -> Word8
accessPixel (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int
y
| Bool
otherwise = Int -> Int -> Word8
accessPixel Int
x (Int
h Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
pixelPerCoeff :: Int16
pixelPerCoeff = Int -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int16) -> Int -> Int16
forall a b. (a -> b) -> a -> b
$ Int
sampWidth Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sampHeight
blockVal :: Int -> Int -> Int16
blockVal Int
x Int
y = [Int16] -> Int16
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Word8 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int16) -> Word8 -> Int16
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Word8
accessPixel (Int
xBase Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
dx) (Int
yBase Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
dy)
| Int
dy <- [Int
0 .. Int
sampHeight Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
, Int
dx <- [Int
0 .. Int
sampWidth Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1] ] Int16 -> Int16 -> Int16
forall a. Integral a => a -> a -> a
`div` Int16
pixelPerCoeff
where xBase :: Int
xBase = Int
blockXBegin Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sampWidth
yBase :: Int
yBase = Int
blockYBegin Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sampHeight
blockXBegin :: Int
blockXBegin = Int
bx Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sampWidth
blockYBegin :: Int
blockYBegin = Int
by Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sampHeight
[ST s ()] -> ST s ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ [(MutableMacroBlock s Int16
MVector (PrimState (ST s)) Int16
block MVector (PrimState (ST s)) Int16 -> Int -> Int16 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x)) (Int16 -> ST s ()) -> Int16 -> ST s ()
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int16
blockVal Int
x Int
y | Int
y <- [Int
0 .. Int
7], Int
x <- [Int
0 .. Int
7] ]
MutableMacroBlock s Int16 -> ST s (MutableMacroBlock s Int16)
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return MutableMacroBlock s Int16
block
serializeMacroBlock :: BoolWriteStateRef s
-> HuffmanWriterCode -> HuffmanWriterCode
-> MutableMacroBlock s Int32
-> ST s ()
serializeMacroBlock :: forall s.
BoolWriteStateRef s
-> HuffmanWriterCode
-> HuffmanWriterCode
-> MutableMacroBlock s Int32
-> ST s ()
serializeMacroBlock !BoolWriteStateRef s
st !HuffmanWriterCode
dcCode !HuffmanWriterCode
acCode !MutableMacroBlock s Int32
blk =
(MutableMacroBlock s Int32
MVector (PrimState (ST s)) Int32
blk MVector (PrimState (ST s)) Int32 -> Int -> ST s Int32
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` Int
0) ST s Int32 -> (Int32 -> ST s ()) -> ST s ()
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Int32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32 -> Int32) -> (Int32 -> ST s ()) -> Int32 -> ST s ()
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Int32 -> ST s ()
encodeDc) ST s () -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Word32, Int) -> ST s ()
writeAcs (Word32
0, Int
1) ST s () -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> ST s ()
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where writeAcs :: (Word32, Int) -> ST s ()
writeAcs acc :: (Word32, Int)
acc@(Word32
_, Int
63) =
(MutableMacroBlock s Int32
MVector (PrimState (ST s)) Int32
blk MVector (PrimState (ST s)) Int32 -> Int -> ST s Int32
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` Int
63) ST s Int32 -> (Int32 -> ST s (Word32, Int)) -> ST s (Word32, Int)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Int32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32 -> Int32)
-> (Int32 -> ST s (Word32, Int)) -> Int32 -> ST s (Word32, Int)
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (Word32, Int) -> Int32 -> ST s (Word32, Int)
encodeAcCoefs (Word32, Int)
acc) ST s (Word32, Int) -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> ST s ()
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
writeAcs acc :: (Word32, Int)
acc@(Word32
_, Int
i ) =
(MutableMacroBlock s Int32
MVector (PrimState (ST s)) Int32
blk MVector (PrimState (ST s)) Int32 -> Int -> ST s Int32
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` Int
i) ST s Int32 -> (Int32 -> ST s (Word32, Int)) -> ST s (Word32, Int)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Int32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32 -> Int32)
-> (Int32 -> ST s (Word32, Int)) -> Int32 -> ST s (Word32, Int)
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (Word32, Int) -> Int32 -> ST s (Word32, Int)
encodeAcCoefs (Word32, Int)
acc) ST s (Word32, Int) -> ((Word32, Int) -> ST s ()) -> ST s ()
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Word32, Int) -> ST s ()
writeAcs
encodeDc :: Int32 -> ST s ()
encodeDc Int32
n = BoolWriteStateRef s -> Word32 -> Int -> ST s ()
forall s. BoolWriteStateRef s -> Word32 -> Int -> ST s ()
writeBits' BoolWriteStateRef s
st (Word16 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
code) (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
bitCount)
ST s () -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word32
ssss Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word32
0) (BoolWriteStateRef s -> Word32 -> Int32 -> ST s ()
forall s. BoolWriteStateRef s -> Word32 -> Int32 -> ST s ()
encodeInt BoolWriteStateRef s
st Word32
ssss Int32
n)
where ssss :: Word32
ssss = Int32 -> Word32
powerOf (Int32 -> Word32) -> Int32 -> Word32
forall a b. (a -> b) -> a -> b
$ Int32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
n
(Word8
bitCount, Word16
code) = HuffmanWriterCode
dcCode HuffmanWriterCode -> Int -> (Word8, Word16)
forall a. Vector a -> Int -> a
`V.unsafeIndex` Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
ssss
encodeAc :: Word32 -> Int32 -> ST s ()
encodeAc Word32
0 Int32
0 = BoolWriteStateRef s -> Word32 -> Int -> ST s ()
forall s. BoolWriteStateRef s -> Word32 -> Int -> ST s ()
writeBits' BoolWriteStateRef s
st (Word16 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
code) (Int -> ST s ()) -> Int -> ST s ()
forall a b. (a -> b) -> a -> b
$ Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
bitCount
where (Word8
bitCount, Word16
code) = HuffmanWriterCode
acCode HuffmanWriterCode -> Int -> (Word8, Word16)
forall a. Vector a -> Int -> a
`V.unsafeIndex` Int
0
encodeAc Word32
zeroCount Int32
n | Word32
zeroCount Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
16 =
BoolWriteStateRef s -> Word32 -> Int -> ST s ()
forall s. BoolWriteStateRef s -> Word32 -> Int -> ST s ()
writeBits' BoolWriteStateRef s
st (Word16 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
code) (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
bitCount) ST s () -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word32 -> Int32 -> ST s ()
encodeAc (Word32
zeroCount Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
16) Int32
n
where (Word8
bitCount, Word16
code) = HuffmanWriterCode
acCode HuffmanWriterCode -> Int -> (Word8, Word16)
forall a. Vector a -> Int -> a
`V.unsafeIndex` Int
0xF0
encodeAc Word32
zeroCount Int32
n =
BoolWriteStateRef s -> Word32 -> Int -> ST s ()
forall s. BoolWriteStateRef s -> Word32 -> Int -> ST s ()
writeBits' BoolWriteStateRef s
st (Word16 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
code) (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
bitCount) ST s () -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> BoolWriteStateRef s -> Word32 -> Int32 -> ST s ()
forall s. BoolWriteStateRef s -> Word32 -> Int32 -> ST s ()
encodeInt BoolWriteStateRef s
st Word32
ssss Int32
n
where rrrr :: Word32
rrrr = Word32
zeroCount Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
4
ssss :: Word32
ssss = Int32 -> Word32
powerOf (Int32 -> Word32) -> Int32 -> Word32
forall a b. (a -> b) -> a -> b
$ Int32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
n
rrrrssss :: Word32
rrrrssss = Word32
rrrr Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32
ssss
(Word8
bitCount, Word16
code) = HuffmanWriterCode
acCode HuffmanWriterCode -> Int -> (Word8, Word16)
forall a. Vector a -> Int -> a
`V.unsafeIndex` Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
rrrrssss
encodeAcCoefs :: (Word32, Int) -> Int32 -> ST s (Word32, Int)
encodeAcCoefs ( Word32
_, Int
63) Int32
0 = Word32 -> Int32 -> ST s ()
encodeAc Word32
0 Int32
0 ST s () -> ST s (Word32, Int) -> ST s (Word32, Int)
forall a b. ST s a -> ST s b -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Word32, Int) -> ST s (Word32, Int)
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word32
0, Int
64)
encodeAcCoefs (Word32
zeroRunLength, Int
i) Int32
0 = (Word32, Int) -> ST s (Word32, Int)
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word32
zeroRunLength Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
1, Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
encodeAcCoefs (Word32
zeroRunLength, Int
i) Int32
n =
Word32 -> Int32 -> ST s ()
encodeAc Word32
zeroRunLength Int32
n ST s () -> ST s (Word32, Int) -> ST s (Word32, Int)
forall a b. ST s a -> ST s b -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Word32, Int) -> ST s (Word32, Int)
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word32
0, Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
encodeMacroBlock :: QuantificationTable
-> MutableMacroBlock s Int32
-> MutableMacroBlock s Int32
-> Int16
-> MutableMacroBlock s Int16
-> ST s (Int32, MutableMacroBlock s Int32)
encodeMacroBlock :: forall s.
MacroBlock Int16
-> MutableMacroBlock s Int32
-> MutableMacroBlock s Int32
-> Int16
-> MutableMacroBlock s Int16
-> ST s (Int32, MutableMacroBlock s Int32)
encodeMacroBlock MacroBlock Int16
quantTableOfComponent MutableMacroBlock s Int32
workData MutableMacroBlock s Int32
finalData Int16
prev_dc MutableMacroBlock s Int16
block = do
MutableMacroBlock s Int32
blk <- MutableMacroBlock s Int32
-> MutableMacroBlock s Int16 -> ST s (MutableMacroBlock s Int32)
forall s.
MutableMacroBlock s Int32
-> MutableMacroBlock s Int16 -> ST s (MutableMacroBlock s Int32)
fastDctLibJpeg MutableMacroBlock s Int32
workData MutableMacroBlock s Int16
block
ST s (MutableMacroBlock s Int32)
-> (MutableMacroBlock s Int32 -> ST s (MutableMacroBlock s Int32))
-> ST s (MutableMacroBlock s Int32)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= MutableMacroBlock s Int32
-> MutableMacroBlock s Int32 -> ST s (MutableMacroBlock s Int32)
forall a s.
Storable a =>
MutableMacroBlock s a
-> MutableMacroBlock s a -> ST s (MutableMacroBlock s a)
zigZagReorderForward MutableMacroBlock s Int32
finalData
ST s (MutableMacroBlock s Int32)
-> (MutableMacroBlock s Int32 -> ST s (MutableMacroBlock s Int32))
-> ST s (MutableMacroBlock s Int32)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= MacroBlock Int16
-> MutableMacroBlock s Int32 -> ST s (MutableMacroBlock s Int32)
forall s.
MacroBlock Int16
-> MutableMacroBlock s Int32 -> ST s (MutableMacroBlock s Int32)
quantize MacroBlock Int16
quantTableOfComponent
Int32
dc <- MutableMacroBlock s Int32
MVector (PrimState (ST s)) Int32
blk MVector (PrimState (ST s)) Int32 -> Int -> ST s Int32
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` Int
0
(MutableMacroBlock s Int32
MVector (PrimState (ST s)) Int32
blk MVector (PrimState (ST s)) Int32 -> Int -> Int32 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` Int
0) (Int32 -> ST s ()) -> Int32 -> ST s ()
forall a b. (a -> b) -> a -> b
$ Int32
dc Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
- Int16 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int16
prev_dc
(Int32, MutableMacroBlock s Int32)
-> ST s (Int32, MutableMacroBlock s Int32)
forall a. a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int32
dc, MutableMacroBlock s Int32
blk)
divUpward :: (Integral a) => a -> a -> a
divUpward :: forall a. Integral a => a -> a -> a
divUpward a
n a
dividor = a
val a -> a -> a
forall a. Num a => a -> a -> a
+ (if a
rest a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
0 then a
1 else a
0)
where (a
val, a
rest) = a
n a -> a -> (a, a)
forall a. Integral a => a -> a -> (a, a)
`divMod` a
dividor
prepareHuffmanTable :: DctComponent -> Word8 -> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable :: DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
classVal Word8
dest HuffmanTable
tableDef =
(JpgHuffmanTableSpec { huffmanTableClass :: DctComponent
huffmanTableClass = DctComponent
classVal
, huffmanTableDest :: Word8
huffmanTableDest = Word8
dest
, huffSizes :: Vector Word8
huffSizes = Vector Word8
sizes
, huffCodes :: Vector (Vector Word8)
huffCodes = Int -> [Vector Word8] -> Vector (Vector Word8)
forall a. Int -> [a] -> Vector a
V.fromListN Int
16
[Int -> [Word8] -> Vector Word8
forall a. Unbox a => Int -> [a] -> Vector a
VU.fromListN (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Word8 -> Int
forall a b. (a -> b) -> a -> b
$ Vector Word8
sizes Vector Word8 -> Int -> Word8
forall a. Unbox a => Vector a -> Int -> a
! Int
i) [Word8]
lst
| (Int
i, [Word8]
lst) <- [Int] -> HuffmanTable -> [(Int, [Word8])]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] HuffmanTable
tableDef ]
}, Word16 -> HuffmanPackedTree
forall a. Storable a => a -> Vector a
VS.singleton Word16
0)
where sizes :: Vector Word8
sizes = Int -> [Word8] -> Vector Word8
forall a. Unbox a => Int -> [a] -> Vector a
VU.fromListN Int
16 ([Word8] -> Vector Word8) -> [Word8] -> Vector Word8
forall a b. (a -> b) -> a -> b
$ ([Word8] -> Word8) -> HuffmanTable -> [Word8]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> ([Word8] -> Int) -> [Word8] -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length) HuffmanTable
tableDef
encodeJpeg :: Image PixelYCbCr8 -> L.ByteString
encodeJpeg :: Image PixelYCbCr8 -> ByteString
encodeJpeg = Word8 -> Image PixelYCbCr8 -> ByteString
encodeJpegAtQuality Word8
50
defaultHuffmanTables :: [(JpgHuffmanTableSpec, HuffmanPackedTree)]
defaultHuffmanTables :: [(JpgHuffmanTableSpec, HuffmanPackedTree)]
defaultHuffmanTables =
[ DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
DcComponent Word8
0 HuffmanTable
defaultDcLumaHuffmanTable
, DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
AcComponent Word8
0 HuffmanTable
defaultAcLumaHuffmanTable
, DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
DcComponent Word8
1 HuffmanTable
defaultDcChromaHuffmanTable
, DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
AcComponent Word8
1 HuffmanTable
defaultAcChromaHuffmanTable
]
lumaQuantTableAtQuality :: Int -> QuantificationTable
lumaQuantTableAtQuality :: Int -> MacroBlock Int16
lumaQuantTableAtQuality Int
qual = Int -> MacroBlock Int16 -> MacroBlock Int16
scaleQuantisationMatrix Int
qual MacroBlock Int16
defaultLumaQuantizationTable
chromaQuantTableAtQuality :: Int -> QuantificationTable
chromaQuantTableAtQuality :: Int -> MacroBlock Int16
chromaQuantTableAtQuality Int
qual =
Int -> MacroBlock Int16 -> MacroBlock Int16
scaleQuantisationMatrix Int
qual MacroBlock Int16
defaultChromaQuantizationTable
zigzaggedQuantificationSpec :: Int -> [JpgQuantTableSpec]
zigzaggedQuantificationSpec :: Int -> [JpgQuantTableSpec]
zigzaggedQuantificationSpec Int
qual =
[ JpgQuantTableSpec { quantPrecision :: Word8
quantPrecision = Word8
0, quantDestination :: Word8
quantDestination = Word8
0, quantTable :: MacroBlock Int16
quantTable = MacroBlock Int16
luma }
, JpgQuantTableSpec { quantPrecision :: Word8
quantPrecision = Word8
0, quantDestination :: Word8
quantDestination = Word8
1, quantTable :: MacroBlock Int16
quantTable = MacroBlock Int16
chroma }
]
where
luma :: MacroBlock Int16
luma = MacroBlock Int16 -> MacroBlock Int16
forall a. (Storable a, Num a) => Vector a -> Vector a
zigZagReorderForwardv (MacroBlock Int16 -> MacroBlock Int16)
-> MacroBlock Int16 -> MacroBlock Int16
forall a b. (a -> b) -> a -> b
$ Int -> MacroBlock Int16
lumaQuantTableAtQuality Int
qual
chroma :: MacroBlock Int16
chroma = MacroBlock Int16 -> MacroBlock Int16
forall a. (Storable a, Num a) => Vector a -> Vector a
zigZagReorderForwardv (MacroBlock Int16 -> MacroBlock Int16)
-> MacroBlock Int16 -> MacroBlock Int16
forall a b. (a -> b) -> a -> b
$ Int -> MacroBlock Int16
chromaQuantTableAtQuality Int
qual
encodeJpegAtQuality :: Word8
-> Image PixelYCbCr8
-> L.ByteString
encodeJpegAtQuality :: Word8 -> Image PixelYCbCr8 -> ByteString
encodeJpegAtQuality Word8
quality = Word8 -> Metadatas -> Image PixelYCbCr8 -> ByteString
encodeJpegAtQualityWithMetadata Word8
quality Metadatas
forall a. Monoid a => a
mempty
data EncoderState = EncoderState
{ EncoderState -> Int
_encComponentIndex :: !Int
, EncoderState -> Int
_encBlockWidth :: !Int
, EncoderState -> Int
_encBlockHeight :: !Int
, EncoderState -> MacroBlock Int16
_encQuantTable :: !QuantificationTable
, EncoderState -> HuffmanWriterCode
_encDcHuffman :: !HuffmanWriterCode
, EncoderState -> HuffmanWriterCode
_encAcHuffman :: !HuffmanWriterCode
}
class (Pixel px, PixelBaseComponent px ~ Word8) => JpgEncodable px where
additionalBlocks :: Image px -> [JpgFrame]
additionalBlocks Image px
_ = []
componentsOfColorSpace :: Image px -> [JpgComponent]
encodingState :: Int -> Image px -> V.Vector EncoderState
imageHuffmanTables :: Image px -> [(JpgHuffmanTableSpec, HuffmanPackedTree)]
imageHuffmanTables Image px
_ = [(JpgHuffmanTableSpec, HuffmanPackedTree)]
defaultHuffmanTables
scanSpecificationOfColorSpace :: Image px -> [JpgScanSpecification]
quantTableSpec :: Image px -> Int -> [JpgQuantTableSpec]
quantTableSpec Image px
_ Int
qual = Int -> [JpgQuantTableSpec] -> [JpgQuantTableSpec]
forall a. Int -> [a] -> [a]
take Int
1 ([JpgQuantTableSpec] -> [JpgQuantTableSpec])
-> [JpgQuantTableSpec] -> [JpgQuantTableSpec]
forall a b. (a -> b) -> a -> b
$ Int -> [JpgQuantTableSpec]
zigzaggedQuantificationSpec Int
qual
maximumSubSamplingOf :: Image px -> Int
maximumSubSamplingOf Image px
_ = Int
1
instance JpgEncodable Pixel8 where
scanSpecificationOfColorSpace :: Image Word8 -> [JpgScanSpecification]
scanSpecificationOfColorSpace Image Word8
_ =
[ JpgScanSpecification { componentSelector :: Word8
componentSelector = Word8
1
, dcEntropyCodingTable :: Word8
dcEntropyCodingTable = Word8
0
, acEntropyCodingTable :: Word8
acEntropyCodingTable = Word8
0
}
]
componentsOfColorSpace :: Image Word8 -> [JpgComponent]
componentsOfColorSpace Image Word8
_ =
[ JpgComponent { componentIdentifier :: Word8
componentIdentifier = Word8
1
, horizontalSamplingFactor :: Word8
horizontalSamplingFactor = Word8
1
, verticalSamplingFactor :: Word8
verticalSamplingFactor = Word8
1
, quantizationTableDest :: Word8
quantizationTableDest = Word8
0
}
]
imageHuffmanTables :: Image Word8 -> [(JpgHuffmanTableSpec, HuffmanPackedTree)]
imageHuffmanTables Image Word8
_ =
[ DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
DcComponent Word8
0 HuffmanTable
defaultDcLumaHuffmanTable
, DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
AcComponent Word8
0 HuffmanTable
defaultAcLumaHuffmanTable
]
encodingState :: Int -> Image Word8 -> Vector EncoderState
encodingState Int
qual Image Word8
_ = EncoderState -> Vector EncoderState
forall a. a -> Vector a
V.singleton EncoderState
{ _encComponentIndex :: Int
_encComponentIndex = Int
0
, _encBlockWidth :: Int
_encBlockWidth = Int
1
, _encBlockHeight :: Int
_encBlockHeight = Int
1
, _encQuantTable :: MacroBlock Int16
_encQuantTable = MacroBlock Int16 -> MacroBlock Int16
forall a. (Storable a, Num a) => Vector a -> Vector a
zigZagReorderForwardv (MacroBlock Int16 -> MacroBlock Int16)
-> MacroBlock Int16 -> MacroBlock Int16
forall a b. (a -> b) -> a -> b
$ Int -> MacroBlock Int16
lumaQuantTableAtQuality Int
qual
, _encDcHuffman :: HuffmanWriterCode
_encDcHuffman = HuffmanTree -> HuffmanWriterCode
makeInverseTable HuffmanTree
defaultDcLumaHuffmanTree
, _encAcHuffman :: HuffmanWriterCode
_encAcHuffman = HuffmanTree -> HuffmanWriterCode
makeInverseTable HuffmanTree
defaultAcLumaHuffmanTree
}
instance JpgEncodable PixelYCbCr8 where
maximumSubSamplingOf :: Image PixelYCbCr8 -> Int
maximumSubSamplingOf Image PixelYCbCr8
_ = Int
2
quantTableSpec :: Image PixelYCbCr8 -> Int -> [JpgQuantTableSpec]
quantTableSpec Image PixelYCbCr8
_ Int
qual = Int -> [JpgQuantTableSpec]
zigzaggedQuantificationSpec Int
qual
scanSpecificationOfColorSpace :: Image PixelYCbCr8 -> [JpgScanSpecification]
scanSpecificationOfColorSpace Image PixelYCbCr8
_ =
[ JpgScanSpecification { componentSelector :: Word8
componentSelector = Word8
1
, dcEntropyCodingTable :: Word8
dcEntropyCodingTable = Word8
0
, acEntropyCodingTable :: Word8
acEntropyCodingTable = Word8
0
}
, JpgScanSpecification { componentSelector :: Word8
componentSelector = Word8
2
, dcEntropyCodingTable :: Word8
dcEntropyCodingTable = Word8
1
, acEntropyCodingTable :: Word8
acEntropyCodingTable = Word8
1
}
, JpgScanSpecification { componentSelector :: Word8
componentSelector = Word8
3
, dcEntropyCodingTable :: Word8
dcEntropyCodingTable = Word8
1
, acEntropyCodingTable :: Word8
acEntropyCodingTable = Word8
1
}
]
componentsOfColorSpace :: Image PixelYCbCr8 -> [JpgComponent]
componentsOfColorSpace Image PixelYCbCr8
_ =
[ JpgComponent { componentIdentifier :: Word8
componentIdentifier = Word8
1
, horizontalSamplingFactor :: Word8
horizontalSamplingFactor = Word8
2
, verticalSamplingFactor :: Word8
verticalSamplingFactor = Word8
2
, quantizationTableDest :: Word8
quantizationTableDest = Word8
0
}
, JpgComponent { componentIdentifier :: Word8
componentIdentifier = Word8
2
, horizontalSamplingFactor :: Word8
horizontalSamplingFactor = Word8
1
, verticalSamplingFactor :: Word8
verticalSamplingFactor = Word8
1
, quantizationTableDest :: Word8
quantizationTableDest = Word8
1
}
, JpgComponent { componentIdentifier :: Word8
componentIdentifier = Word8
3
, horizontalSamplingFactor :: Word8
horizontalSamplingFactor = Word8
1
, verticalSamplingFactor :: Word8
verticalSamplingFactor = Word8
1
, quantizationTableDest :: Word8
quantizationTableDest = Word8
1
}
]
encodingState :: Int -> Image PixelYCbCr8 -> Vector EncoderState
encodingState Int
qual Image PixelYCbCr8
_ = Int -> [EncoderState] -> Vector EncoderState
forall a. Int -> [a] -> Vector a
V.fromListN Int
3 [EncoderState
lumaState, EncoderState
chromaState, EncoderState
chromaState { _encComponentIndex = 2 }]
where
lumaState :: EncoderState
lumaState = EncoderState
{ _encComponentIndex :: Int
_encComponentIndex = Int
0
, _encBlockWidth :: Int
_encBlockWidth = Int
2
, _encBlockHeight :: Int
_encBlockHeight = Int
2
, _encQuantTable :: MacroBlock Int16
_encQuantTable = MacroBlock Int16 -> MacroBlock Int16
forall a. (Storable a, Num a) => Vector a -> Vector a
zigZagReorderForwardv (MacroBlock Int16 -> MacroBlock Int16)
-> MacroBlock Int16 -> MacroBlock Int16
forall a b. (a -> b) -> a -> b
$ Int -> MacroBlock Int16
lumaQuantTableAtQuality Int
qual
, _encDcHuffman :: HuffmanWriterCode
_encDcHuffman = HuffmanTree -> HuffmanWriterCode
makeInverseTable HuffmanTree
defaultDcLumaHuffmanTree
, _encAcHuffman :: HuffmanWriterCode
_encAcHuffman = HuffmanTree -> HuffmanWriterCode
makeInverseTable HuffmanTree
defaultAcLumaHuffmanTree
}
chromaState :: EncoderState
chromaState = EncoderState
{ _encComponentIndex :: Int
_encComponentIndex = Int
1
, _encBlockWidth :: Int
_encBlockWidth = Int
1
, _encBlockHeight :: Int
_encBlockHeight = Int
1
, _encQuantTable :: MacroBlock Int16
_encQuantTable = MacroBlock Int16 -> MacroBlock Int16
forall a. (Storable a, Num a) => Vector a -> Vector a
zigZagReorderForwardv (MacroBlock Int16 -> MacroBlock Int16)
-> MacroBlock Int16 -> MacroBlock Int16
forall a b. (a -> b) -> a -> b
$ Int -> MacroBlock Int16
chromaQuantTableAtQuality Int
qual
, _encDcHuffman :: HuffmanWriterCode
_encDcHuffman = HuffmanTree -> HuffmanWriterCode
makeInverseTable HuffmanTree
defaultDcChromaHuffmanTree
, _encAcHuffman :: HuffmanWriterCode
_encAcHuffman = HuffmanTree -> HuffmanWriterCode
makeInverseTable HuffmanTree
defaultAcChromaHuffmanTree
}
instance JpgEncodable PixelRGB8 where
additionalBlocks :: Image PixelRGB8 -> [JpgFrame]
additionalBlocks Image PixelRGB8
_ = [JpgAdobeApp14 -> JpgFrame
JpgAdobeAPP14 JpgAdobeApp14
adobe14] where
adobe14 :: JpgAdobeApp14
adobe14 = JpgAdobeApp14
{ _adobeDctVersion :: Word16
_adobeDctVersion = Word16
100
, _adobeFlag0 :: Word16
_adobeFlag0 = Word16
0
, _adobeFlag1 :: Word16
_adobeFlag1 = Word16
0
, _adobeTransform :: AdobeTransform
_adobeTransform = AdobeTransform
AdobeUnknown
}
imageHuffmanTables :: Image PixelRGB8 -> [(JpgHuffmanTableSpec, HuffmanPackedTree)]
imageHuffmanTables Image PixelRGB8
_ =
[ DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
DcComponent Word8
0 HuffmanTable
defaultDcLumaHuffmanTable
, DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
AcComponent Word8
0 HuffmanTable
defaultAcLumaHuffmanTable
]
scanSpecificationOfColorSpace :: Image PixelRGB8 -> [JpgScanSpecification]
scanSpecificationOfColorSpace Image PixelRGB8
_ = (Char -> JpgScanSpecification) -> String -> [JpgScanSpecification]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> JpgScanSpecification
forall {a}. Enum a => a -> JpgScanSpecification
build String
"RGB" where
build :: a -> JpgScanSpecification
build a
c = JpgScanSpecification
{ componentSelector :: Word8
componentSelector = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ a -> Int
forall a. Enum a => a -> Int
fromEnum a
c
, dcEntropyCodingTable :: Word8
dcEntropyCodingTable = Word8
0
, acEntropyCodingTable :: Word8
acEntropyCodingTable = Word8
0
}
componentsOfColorSpace :: Image PixelRGB8 -> [JpgComponent]
componentsOfColorSpace Image PixelRGB8
_ = (Char -> JpgComponent) -> String -> [JpgComponent]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> JpgComponent
forall {a}. Enum a => a -> JpgComponent
build String
"RGB" where
build :: a -> JpgComponent
build a
c = JpgComponent
{ componentIdentifier :: Word8
componentIdentifier = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ a -> Int
forall a. Enum a => a -> Int
fromEnum a
c
, horizontalSamplingFactor :: Word8
horizontalSamplingFactor = Word8
1
, verticalSamplingFactor :: Word8
verticalSamplingFactor = Word8
1
, quantizationTableDest :: Word8
quantizationTableDest = Word8
0
}
encodingState :: Int -> Image PixelRGB8 -> Vector EncoderState
encodingState Int
qual Image PixelRGB8
_ = Int -> [EncoderState] -> Vector EncoderState
forall a. Int -> [a] -> Vector a
V.fromListN Int
3 ([EncoderState] -> Vector EncoderState)
-> [EncoderState] -> Vector EncoderState
forall a b. (a -> b) -> a -> b
$ (Int -> EncoderState) -> [Int] -> [EncoderState]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> EncoderState
build [Int
0 .. Int
2] where
build :: Int -> EncoderState
build Int
ix = EncoderState
{ _encComponentIndex :: Int
_encComponentIndex = Int
ix
, _encBlockWidth :: Int
_encBlockWidth = Int
1
, _encBlockHeight :: Int
_encBlockHeight = Int
1
, _encQuantTable :: MacroBlock Int16
_encQuantTable = MacroBlock Int16 -> MacroBlock Int16
forall a. (Storable a, Num a) => Vector a -> Vector a
zigZagReorderForwardv (MacroBlock Int16 -> MacroBlock Int16)
-> MacroBlock Int16 -> MacroBlock Int16
forall a b. (a -> b) -> a -> b
$ Int -> MacroBlock Int16
lumaQuantTableAtQuality Int
qual
, _encDcHuffman :: HuffmanWriterCode
_encDcHuffman = HuffmanTree -> HuffmanWriterCode
makeInverseTable HuffmanTree
defaultDcLumaHuffmanTree
, _encAcHuffman :: HuffmanWriterCode
_encAcHuffman = HuffmanTree -> HuffmanWriterCode
makeInverseTable HuffmanTree
defaultAcLumaHuffmanTree
}
instance JpgEncodable PixelCMYK8 where
additionalBlocks :: Image PixelCMYK8 -> [JpgFrame]
additionalBlocks Image PixelCMYK8
_ = [] where
_adobe14 :: JpgAdobeApp14
_adobe14 = JpgAdobeApp14
{ _adobeDctVersion :: Word16
_adobeDctVersion = Word16
100
, _adobeFlag0 :: Word16
_adobeFlag0 = Word16
32768
, _adobeFlag1 :: Word16
_adobeFlag1 = Word16
0
, _adobeTransform :: AdobeTransform
_adobeTransform = AdobeTransform
AdobeYCck
}
imageHuffmanTables :: Image PixelCMYK8 -> [(JpgHuffmanTableSpec, HuffmanPackedTree)]
imageHuffmanTables Image PixelCMYK8
_ =
[ DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
DcComponent Word8
0 HuffmanTable
defaultDcLumaHuffmanTable
, DctComponent
-> Word8
-> HuffmanTable
-> (JpgHuffmanTableSpec, HuffmanPackedTree)
prepareHuffmanTable DctComponent
AcComponent Word8
0 HuffmanTable
defaultAcLumaHuffmanTable
]
scanSpecificationOfColorSpace :: Image PixelCMYK8 -> [JpgScanSpecification]
scanSpecificationOfColorSpace Image PixelCMYK8
_ = (Char -> JpgScanSpecification) -> String -> [JpgScanSpecification]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> JpgScanSpecification
forall {a}. Enum a => a -> JpgScanSpecification
build String
"CMYK" where
build :: a -> JpgScanSpecification
build a
c = JpgScanSpecification
{ componentSelector :: Word8
componentSelector = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ a -> Int
forall a. Enum a => a -> Int
fromEnum a
c
, dcEntropyCodingTable :: Word8
dcEntropyCodingTable = Word8
0
, acEntropyCodingTable :: Word8
acEntropyCodingTable = Word8
0
}
componentsOfColorSpace :: Image PixelCMYK8 -> [JpgComponent]
componentsOfColorSpace Image PixelCMYK8
_ = (Char -> JpgComponent) -> String -> [JpgComponent]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> JpgComponent
forall {a}. Enum a => a -> JpgComponent
build String
"CMYK" where
build :: a -> JpgComponent
build a
c = JpgComponent
{ componentIdentifier :: Word8
componentIdentifier = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ a -> Int
forall a. Enum a => a -> Int
fromEnum a
c
, horizontalSamplingFactor :: Word8
horizontalSamplingFactor = Word8
1
, verticalSamplingFactor :: Word8
verticalSamplingFactor = Word8
1
, quantizationTableDest :: Word8
quantizationTableDest = Word8
0
}
encodingState :: Int -> Image PixelCMYK8 -> Vector EncoderState
encodingState Int
qual Image PixelCMYK8
_ = Int -> [EncoderState] -> Vector EncoderState
forall a. Int -> [a] -> Vector a
V.fromListN Int
4 ([EncoderState] -> Vector EncoderState)
-> [EncoderState] -> Vector EncoderState
forall a b. (a -> b) -> a -> b
$ (Int -> EncoderState) -> [Int] -> [EncoderState]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> EncoderState
build [Int
0 .. Int
3] where
build :: Int -> EncoderState
build Int
ix = EncoderState
{ _encComponentIndex :: Int
_encComponentIndex = Int
ix
, _encBlockWidth :: Int
_encBlockWidth = Int
1
, _encBlockHeight :: Int
_encBlockHeight = Int
1
, _encQuantTable :: MacroBlock Int16
_encQuantTable = MacroBlock Int16 -> MacroBlock Int16
forall a. (Storable a, Num a) => Vector a -> Vector a
zigZagReorderForwardv (MacroBlock Int16 -> MacroBlock Int16)
-> MacroBlock Int16 -> MacroBlock Int16
forall a b. (a -> b) -> a -> b
$ Int -> MacroBlock Int16
lumaQuantTableAtQuality Int
qual
, _encDcHuffman :: HuffmanWriterCode
_encDcHuffman = HuffmanTree -> HuffmanWriterCode
makeInverseTable HuffmanTree
defaultDcLumaHuffmanTree
, _encAcHuffman :: HuffmanWriterCode
_encAcHuffman = HuffmanTree -> HuffmanWriterCode
makeInverseTable HuffmanTree
defaultAcLumaHuffmanTree
}
encodeJpegAtQualityWithMetadata :: Word8
-> Metadatas
-> Image PixelYCbCr8
-> L.ByteString
encodeJpegAtQualityWithMetadata :: Word8 -> Metadatas -> Image PixelYCbCr8 -> ByteString
encodeJpegAtQualityWithMetadata = Word8 -> Metadatas -> Image PixelYCbCr8 -> ByteString
forall px.
JpgEncodable px =>
Word8 -> Metadatas -> Image px -> ByteString
encodeDirectJpegAtQualityWithMetadata
encodeDirectJpegAtQualityWithMetadata :: forall px. (JpgEncodable px)
=> Word8
-> Metadatas
-> Image px
-> L.ByteString
encodeDirectJpegAtQualityWithMetadata :: forall px.
JpgEncodable px =>
Word8 -> Metadatas -> Image px -> ByteString
encodeDirectJpegAtQualityWithMetadata Word8
quality Metadatas
metas Image px
img = JpgImage -> ByteString
forall a. Binary a => a -> ByteString
encode JpgImage
finalImage where
!w :: Int
w = Image px -> Int
forall a. Image a -> Int
imageWidth Image px
img
!h :: Int
h = Image px -> Int
forall a. Image a -> Int
imageHeight Image px
img
!exifMeta :: [JpgFrame]
exifMeta = case Metadatas -> [ImageFileDirectory]
encodeTiffStringMetadata Metadatas
metas of
[] -> []
[ImageFileDirectory]
lst -> [[ImageFileDirectory] -> JpgFrame
JpgExif [ImageFileDirectory]
lst]
finalImage :: JpgImage
finalImage = [JpgFrame] -> JpgImage
JpgImage ([JpgFrame] -> JpgImage) -> [JpgFrame] -> JpgImage
forall a b. (a -> b) -> a -> b
$
Metadatas -> [JpgFrame]
encodeMetadatas Metadatas
metas [JpgFrame] -> [JpgFrame] -> [JpgFrame]
forall a. [a] -> [a] -> [a]
++
[JpgFrame]
exifMeta [JpgFrame] -> [JpgFrame] -> [JpgFrame]
forall a. [a] -> [a] -> [a]
++
Image px -> [JpgFrame]
forall px. JpgEncodable px => Image px -> [JpgFrame]
additionalBlocks Image px
img [JpgFrame] -> [JpgFrame] -> [JpgFrame]
forall a. [a] -> [a] -> [a]
++
[ [JpgQuantTableSpec] -> JpgFrame
JpgQuantTable ([JpgQuantTableSpec] -> JpgFrame)
-> [JpgQuantTableSpec] -> JpgFrame
forall a b. (a -> b) -> a -> b
$ Image px -> Int -> [JpgQuantTableSpec]
forall px.
JpgEncodable px =>
Image px -> Int -> [JpgQuantTableSpec]
quantTableSpec Image px
img (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
quality)
, JpgFrameKind -> JpgFrameHeader -> JpgFrame
JpgScans JpgFrameKind
JpgBaselineDCTHuffman JpgFrameHeader
hdr
, [(JpgHuffmanTableSpec, HuffmanPackedTree)] -> JpgFrame
JpgHuffmanTable ([(JpgHuffmanTableSpec, HuffmanPackedTree)] -> JpgFrame)
-> [(JpgHuffmanTableSpec, HuffmanPackedTree)] -> JpgFrame
forall a b. (a -> b) -> a -> b
$ Image px -> [(JpgHuffmanTableSpec, HuffmanPackedTree)]
forall px.
JpgEncodable px =>
Image px -> [(JpgHuffmanTableSpec, HuffmanPackedTree)]
imageHuffmanTables Image px
img
, JpgScanHeader -> ByteString -> JpgFrame
JpgScanBlob JpgScanHeader
scanHeader ByteString
encodedImage
]
!outputComponentCount :: Int
outputComponentCount = px -> Int
forall a. Pixel a => a -> Int
componentCount (px
forall a. HasCallStack => a
undefined :: px)
scanHeader :: JpgScanHeader
scanHeader = JpgScanHeader
scanHeader'{ scanLength = fromIntegral $ calculateSize scanHeader' }
scanHeader' :: JpgScanHeader
scanHeader' = JpgScanHeader
{ scanLength :: Word16
scanLength = Word16
0
, scanComponentCount :: Word8
scanComponentCount = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
outputComponentCount
, scans :: [JpgScanSpecification]
scans = Image px -> [JpgScanSpecification]
forall px. JpgEncodable px => Image px -> [JpgScanSpecification]
scanSpecificationOfColorSpace Image px
img
, spectralSelection :: (Word8, Word8)
spectralSelection = (Word8
0, Word8
63)
, successiveApproxHigh :: Word8
successiveApproxHigh = Word8
0
, successiveApproxLow :: Word8
successiveApproxLow = Word8
0
}
hdr :: JpgFrameHeader
hdr = JpgFrameHeader
hdr' { jpgFrameHeaderLength = fromIntegral $ calculateSize hdr' }
hdr' :: JpgFrameHeader
hdr' = JpgFrameHeader
{ jpgFrameHeaderLength :: Word16
jpgFrameHeaderLength = Word16
0
, jpgSamplePrecision :: Word8
jpgSamplePrecision = Word8
8
, jpgHeight :: Word16
jpgHeight = Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
h
, jpgWidth :: Word16
jpgWidth = Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
w
, jpgImageComponentCount :: Word8
jpgImageComponentCount = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
outputComponentCount
, jpgComponents :: [JpgComponent]
jpgComponents = Image px -> [JpgComponent]
forall px. JpgEncodable px => Image px -> [JpgComponent]
componentsOfColorSpace Image px
img
}
!maxSampling :: Int
maxSampling = Image px -> Int
forall px. JpgEncodable px => Image px -> Int
maximumSubSamplingOf Image px
img
!horizontalMetaBlockCount :: Int
horizontalMetaBlockCount = Int
w Int -> Int -> Int
forall a. Integral a => a -> a -> a
`divUpward` (Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
maxSampling)
!verticalMetaBlockCount :: Int
verticalMetaBlockCount = Int
h Int -> Int -> Int
forall a. Integral a => a -> a -> a
`divUpward` (Int
forall a. Num a => a
dctBlockSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
maxSampling)
!componentDef :: Vector EncoderState
componentDef = Int -> Image px -> Vector EncoderState
forall px.
JpgEncodable px =>
Int -> Image px -> Vector EncoderState
encodingState (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
quality) Image px
img
encodedImage :: ByteString
encodedImage = (forall s. ST s ByteString) -> ByteString
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s ByteString) -> ByteString)
-> (forall s. ST s ByteString) -> ByteString
forall a b. (a -> b) -> a -> b
$ do
MVector s Int16
dc_table <- Int -> Int16 -> ST s (MVector (PrimState (ST s)) Int16)
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> a -> m (MVector (PrimState m) a)
M.replicate Int
outputComponentCount Int16
0
MVector s Int16
block <- ST s (MVector s Int16)
forall a s. (Storable a, Num a) => ST s (MutableMacroBlock s a)
createEmptyMutableMacroBlock
MutableMacroBlock s Int32
workData <- ST s (MutableMacroBlock s Int32)
forall a s. (Storable a, Num a) => ST s (MutableMacroBlock s a)
createEmptyMutableMacroBlock
MutableMacroBlock s Int32
zigzaged <- ST s (MutableMacroBlock s Int32)
forall a s. (Storable a, Num a) => ST s (MutableMacroBlock s a)
createEmptyMutableMacroBlock
BoolWriteStateRef s
writeState <- ST s (BoolWriteStateRef s)
forall s. ST s (BoolWriteStateRef s)
newWriteStateRef
Int -> Int -> (Int -> Int -> ST s ()) -> ST s ()
forall (m :: * -> *).
Monad m =>
Int -> Int -> (Int -> Int -> m ()) -> m ()
rasterMap Int
horizontalMetaBlockCount Int
verticalMetaBlockCount ((Int -> Int -> ST s ()) -> ST s ())
-> (Int -> Int -> ST s ()) -> ST s ()
forall a b. (a -> b) -> a -> b
$ \Int
mx Int
my ->
Vector EncoderState -> (EncoderState -> ST s ()) -> ST s ()
forall (m :: * -> *) a b. Monad m => Vector a -> (a -> m b) -> m ()
V.forM_ Vector EncoderState
componentDef ((EncoderState -> ST s ()) -> ST s ())
-> (EncoderState -> ST s ()) -> ST s ()
forall a b. (a -> b) -> a -> b
$ \(EncoderState Int
comp Int
sizeX Int
sizeY MacroBlock Int16
table HuffmanWriterCode
dc HuffmanWriterCode
ac) ->
let !xSamplingFactor :: Int
xSamplingFactor = Int
maxSampling Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
sizeX Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
!ySamplingFactor :: Int
ySamplingFactor = Int
maxSampling Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
sizeY Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
!extractor :: Int -> Int -> Int -> ST s (MVector s Int16)
extractor = Image px
-> MVector s Int16
-> Int
-> Int
-> Int
-> Int
-> Int
-> Int
-> ST s (MVector s Int16)
forall s px.
(PixelBaseComponent px ~ Word8) =>
Image px
-> MutableMacroBlock s Int16
-> Int
-> Int
-> Int
-> Int
-> Int
-> Int
-> ST s (MutableMacroBlock s Int16)
extractBlock Image px
img MVector s Int16
block Int
xSamplingFactor Int
ySamplingFactor Int
outputComponentCount
in
Int -> Int -> (Int -> Int -> ST s ()) -> ST s ()
forall (m :: * -> *).
Monad m =>
Int -> Int -> (Int -> Int -> m ()) -> m ()
rasterMap Int
sizeX Int
sizeY ((Int -> Int -> ST s ()) -> ST s ())
-> (Int -> Int -> ST s ()) -> ST s ()
forall a b. (a -> b) -> a -> b
$ \Int
subX Int
subY -> do
let !blockY :: Int
blockY = Int
my Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sizeY Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
subY
!blockX :: Int
blockX = Int
mx Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sizeX Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
subX
Int16
prev_dc <- MVector s Int16
MVector (PrimState (ST s)) Int16
dc_table MVector (PrimState (ST s)) Int16 -> Int -> ST s Int16
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> m a
`M.unsafeRead` Int
comp
MVector s Int16
extracted <- Int -> Int -> Int -> ST s (MVector s Int16)
extractor Int
comp Int
blockX Int
blockY
(Int32
dc_coeff, MutableMacroBlock s Int32
neo_block) <- MacroBlock Int16
-> MutableMacroBlock s Int32
-> MutableMacroBlock s Int32
-> Int16
-> MVector s Int16
-> ST s (Int32, MutableMacroBlock s Int32)
forall s.
MacroBlock Int16
-> MutableMacroBlock s Int32
-> MutableMacroBlock s Int32
-> Int16
-> MutableMacroBlock s Int16
-> ST s (Int32, MutableMacroBlock s Int32)
encodeMacroBlock MacroBlock Int16
table MutableMacroBlock s Int32
workData MutableMacroBlock s Int32
zigzaged Int16
prev_dc MVector s Int16
extracted
(MVector s Int16
MVector (PrimState (ST s)) Int16
dc_table MVector (PrimState (ST s)) Int16 -> Int -> Int16 -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` Int
comp) (Int16 -> ST s ()) -> Int16 -> ST s ()
forall a b. (a -> b) -> a -> b
$ Int32 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
dc_coeff
BoolWriteStateRef s
-> HuffmanWriterCode
-> HuffmanWriterCode
-> MutableMacroBlock s Int32
-> ST s ()
forall s.
BoolWriteStateRef s
-> HuffmanWriterCode
-> HuffmanWriterCode
-> MutableMacroBlock s Int32
-> ST s ()
serializeMacroBlock BoolWriteStateRef s
writeState HuffmanWriterCode
dc HuffmanWriterCode
ac MutableMacroBlock s Int32
neo_block
BoolWriteStateRef s -> ST s ByteString
forall s. BoolWriteStateRef s -> ST s ByteString
finalizeBoolWriter BoolWriteStateRef s
writeState