{-# LANGUAGE TupleSections #-}
{-# LANGUAGE FlexibleContexts #-}
-- | Module used by the jpeg decoder internally, shouldn't be used

-- in user code.

module Codec.Picture.Jpg.Internal.DefaultTable( DctComponent( .. )
                                     , HuffmanTree( .. )
                                     , HuffmanTable
                                     , HuffmanPackedTree
                                     , MacroBlock
                                     , QuantificationTable
                                     , HuffmanWriterCode 
                                     , scaleQuantisationMatrix
                                     , makeMacroBlock
                                     , makeInverseTable
                                     , buildHuffmanTree
                                     , packHuffmanTree
                                     , huffmanPackedDecode

                                     , defaultChromaQuantizationTable

                                     , defaultLumaQuantizationTable

                                     , defaultAcChromaHuffmanTree
                                     , defaultAcChromaHuffmanTable

                                     , defaultAcLumaHuffmanTree 
                                     , defaultAcLumaHuffmanTable 

                                     , defaultDcChromaHuffmanTree 
                                     , defaultDcChromaHuffmanTable

                                     , defaultDcLumaHuffmanTree
                                     , defaultDcLumaHuffmanTable
                                     ) where

import Data.Int( Int16 )
import Foreign.Storable ( Storable )
import Control.Monad.ST( runST )
import qualified Data.Vector.Storable as SV
import qualified Data.Vector as V
import Data.Bits( unsafeShiftL, (.|.), (.&.) )
import Data.Word( Word8, Word16 )
import Data.List( foldl' )
import qualified Data.Vector.Storable.Mutable as M

import Codec.Picture.BitWriter

-- | Tree storing the code used for huffman encoding.

data HuffmanTree = Branch HuffmanTree HuffmanTree -- ^ If bit is 0 take the first subtree, if 1, the right.

                 | Leaf Word8       -- ^ We should output the value

                 | Empty            -- ^ no value present

                 deriving (HuffmanTree -> HuffmanTree -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HuffmanTree -> HuffmanTree -> Bool
$c/= :: HuffmanTree -> HuffmanTree -> Bool
== :: HuffmanTree -> HuffmanTree -> Bool
$c== :: HuffmanTree -> HuffmanTree -> Bool
Eq, Int -> HuffmanTree -> ShowS
[HuffmanTree] -> ShowS
HuffmanTree -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HuffmanTree] -> ShowS
$cshowList :: [HuffmanTree] -> ShowS
show :: HuffmanTree -> String
$cshow :: HuffmanTree -> String
showsPrec :: Int -> HuffmanTree -> ShowS
$cshowsPrec :: Int -> HuffmanTree -> ShowS
Show)

type HuffmanPackedTree = SV.Vector Word16

type HuffmanWriterCode = V.Vector (Word8, Word16)

packHuffmanTree :: HuffmanTree -> HuffmanPackedTree
packHuffmanTree :: HuffmanTree -> HuffmanPackedTree
packHuffmanTree HuffmanTree
tree = forall a. (forall s. ST s a) -> a
runST forall a b. (a -> b) -> a -> b
$ do
    MVector (PrimState (ST s)) Word16
table <- forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> a -> m (MVector (PrimState m) a)
M.replicate Int
512 Word16
0x8000
    let aux :: HuffmanTree -> Int -> ST s Int
aux (HuffmanTree
Empty) Int
idx = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
+ Int
1
        aux (Leaf Word8
v) Int
idx = do
            (MVector (PrimState (ST s)) Word16
table forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` Int
idx) forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
v forall a. Bits a => a -> a -> a
.|. Word16
0x4000
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
+ Int
1

        aux (Branch i1 :: HuffmanTree
i1@(Leaf Word8
_) i2 :: HuffmanTree
i2@(Leaf Word8
_)) Int
idx =
            HuffmanTree -> Int -> ST s Int
aux HuffmanTree
i1 Int
idx forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HuffmanTree -> Int -> ST s Int
aux HuffmanTree
i2

        aux (Branch i1 :: HuffmanTree
i1@(Leaf Word8
_) HuffmanTree
i2) Int
idx = do
            Int
_ <- HuffmanTree -> Int -> ST s Int
aux HuffmanTree
i1 Int
idx
            Int
ix2 <- HuffmanTree -> Int -> ST s Int
aux HuffmanTree
i2 forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
+ Int
2
            (MVector (PrimState (ST s)) Word16
table forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx forall a. Num a => a -> a -> a
+ Int
1)) forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
+ Int
2
            forall (m :: * -> *) a. Monad m => a -> m a
return Int
ix2

        aux (Branch HuffmanTree
i1 i2 :: HuffmanTree
i2@(Leaf Word8
_)) Int
idx = do
            Int
ix1 <- HuffmanTree -> Int -> ST s Int
aux HuffmanTree
i1 (Int
idx forall a. Num a => a -> a -> a
+ Int
2)
            Int
_ <- HuffmanTree -> Int -> ST s Int
aux HuffmanTree
i2 (Int
idx forall a. Num a => a -> a -> a
+ Int
1)
            (MVector (PrimState (ST s)) Word16
table forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` Int
idx) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
+ Int
2
            forall (m :: * -> *) a. Monad m => a -> m a
return Int
ix1

        aux (Branch HuffmanTree
i1 HuffmanTree
i2) Int
idx = do
            Int
ix1 <- HuffmanTree -> Int -> ST s Int
aux HuffmanTree
i1 (Int
idx forall a. Num a => a -> a -> a
+ Int
2)
            Int
ix2 <- HuffmanTree -> Int -> ST s Int
aux HuffmanTree
i2 Int
ix1
            (MVector (PrimState (ST s)) Word16
table forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` Int
idx) (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Int
idx forall a. Num a => a -> a -> a
+ Int
2)
            (MVector (PrimState (ST s)) Word16
table forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
idx forall a. Num a => a -> a -> a
+ Int
1)) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ix1)
            forall (m :: * -> *) a. Monad m => a -> m a
return Int
ix2
    Int
_ <- HuffmanTree -> Int -> ST s Int
aux HuffmanTree
tree Int
0
    forall a (m :: * -> *).
(Storable a, PrimMonad m) =>
MVector (PrimState m) a -> m (Vector a)
SV.unsafeFreeze MVector (PrimState (ST s)) Word16
table

makeInverseTable :: HuffmanTree -> HuffmanWriterCode
makeInverseTable :: HuffmanTree -> HuffmanWriterCode
makeInverseTable HuffmanTree
t = forall a. Int -> a -> Vector a
V.replicate Int
255 (Word8
0,Word16
0) forall a. Vector a -> [(Int, a)] -> Vector a
V.// forall {t} {a} {t}.
(Num a, Num t, Num t, Bits t) =>
t -> t -> HuffmanTree -> [(a, (t, t))]
inner Word8
0 Word16
0 HuffmanTree
t
  where inner :: t -> t -> HuffmanTree -> [(a, (t, t))]
inner t
_     t
_     HuffmanTree
Empty   = []
        inner t
depth t
code (Leaf Word8
v) = [(forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
v, (t
depth, t
code))]
        inner t
depth t
code (Branch HuffmanTree
l HuffmanTree
r) =
          t -> t -> HuffmanTree -> [(a, (t, t))]
inner (t
depth forall a. Num a => a -> a -> a
+ t
1) t
shifted HuffmanTree
l forall a. [a] -> [a] -> [a]
++ t -> t -> HuffmanTree -> [(a, (t, t))]
inner (t
depth forall a. Num a => a -> a -> a
+ t
1) (t
shifted forall a. Bits a => a -> a -> a
.|. t
1) HuffmanTree
r
            where shifted :: t
shifted = t
code forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
1

-- | Represent a compact array of 8 * 8 values. The size

-- is not guarenteed by type system, but if makeMacroBlock is

-- used, everything should be fine size-wise

type MacroBlock a = SV.Vector a

type QuantificationTable = MacroBlock Int16

-- | Helper function to create pure macro block of the good size.

makeMacroBlock :: (Storable a) => [a] -> MacroBlock a
makeMacroBlock :: forall a. Storable a => [a] -> MacroBlock a
makeMacroBlock = forall a. Storable a => Int -> [a] -> Vector a
SV.fromListN Int
64

-- | Enumeration used to search in the tables for different components.

data DctComponent = DcComponent | AcComponent
    deriving (DctComponent -> DctComponent -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DctComponent -> DctComponent -> Bool
$c/= :: DctComponent -> DctComponent -> Bool
== :: DctComponent -> DctComponent -> Bool
$c== :: DctComponent -> DctComponent -> Bool
Eq, Int -> DctComponent -> ShowS
[DctComponent] -> ShowS
DctComponent -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DctComponent] -> ShowS
$cshowList :: [DctComponent] -> ShowS
show :: DctComponent -> String
$cshow :: DctComponent -> String
showsPrec :: Int -> DctComponent -> ShowS
$cshowsPrec :: Int -> DctComponent -> ShowS
Show)

-- | Transform parsed coefficients from the jpeg header to a

-- tree which can be used to decode data.

buildHuffmanTree :: [[Word8]] -> HuffmanTree
buildHuffmanTree :: [[Word8]] -> HuffmanTree
buildHuffmanTree [[Word8]]
table = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' forall {a}.
(Eq a, Num a) =>
HuffmanTree -> (a, Word8) -> HuffmanTree
insertHuffmanVal HuffmanTree
Empty
                       forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(Int
i, [Word8]
t) -> forall a b. (a -> b) -> [a] -> [b]
map (Int
i forall a. Num a => a -> a -> a
+ Int
1,) [Word8]
t)
                       forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip ([Int
0..] :: [Int]) [[Word8]]
table
  where isTreeFullyDefined :: HuffmanTree -> Bool
isTreeFullyDefined HuffmanTree
Empty = Bool
False
        isTreeFullyDefined (Leaf Word8
_) = Bool
True
        isTreeFullyDefined (Branch HuffmanTree
l HuffmanTree
r) = HuffmanTree -> Bool
isTreeFullyDefined HuffmanTree
l Bool -> Bool -> Bool
&& HuffmanTree -> Bool
isTreeFullyDefined HuffmanTree
r

        insertHuffmanVal :: HuffmanTree -> (a, Word8) -> HuffmanTree
insertHuffmanVal HuffmanTree
Empty (a
0, Word8
val) = Word8 -> HuffmanTree
Leaf Word8
val
        insertHuffmanVal HuffmanTree
Empty (a
d, Word8
val) = HuffmanTree -> HuffmanTree -> HuffmanTree
Branch (HuffmanTree -> (a, Word8) -> HuffmanTree
insertHuffmanVal HuffmanTree
Empty (a
d forall a. Num a => a -> a -> a
- a
1, Word8
val)) HuffmanTree
Empty
        insertHuffmanVal (Branch HuffmanTree
l HuffmanTree
r) (a
d, Word8
val)
            | HuffmanTree -> Bool
isTreeFullyDefined HuffmanTree
l = HuffmanTree -> HuffmanTree -> HuffmanTree
Branch HuffmanTree
l (HuffmanTree -> (a, Word8) -> HuffmanTree
insertHuffmanVal HuffmanTree
r (a
d forall a. Num a => a -> a -> a
- a
1, Word8
val))
            | Bool
otherwise            = HuffmanTree -> HuffmanTree -> HuffmanTree
Branch (HuffmanTree -> (a, Word8) -> HuffmanTree
insertHuffmanVal HuffmanTree
l (a
d forall a. Num a => a -> a -> a
- a
1, Word8
val)) HuffmanTree
r
        insertHuffmanVal (Leaf Word8
_) (a, Word8)
_ = forall a. HasCallStack => String -> a
error String
"Inserting in value, shouldn't happen"

scaleQuantisationMatrix :: Int -> QuantificationTable -> QuantificationTable 
scaleQuantisationMatrix :: Int -> QuantificationTable -> QuantificationTable
scaleQuantisationMatrix Int
quality
    | Int
quality forall a. Ord a => a -> a -> Bool
< Int
0 = Int -> QuantificationTable -> QuantificationTable
scaleQuantisationMatrix Int
0
        -- shouldn't show much difference than with 1,

        -- but hey, at least we're complete

    | Int
quality forall a. Eq a => a -> a -> Bool
== Int
0 = forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
SV.map (forall {b} {a} {c}. (Integral b, Integral a, Num c) => b -> a -> c
scale (Int
10000 :: Int))
    | Int
quality forall a. Ord a => a -> a -> Bool
< Int
50 = let qq :: Int
qq = Int
5000 forall a. Integral a => a -> a -> a
`div` Int
quality
                     in forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
SV.map (forall {b} {a} {c}. (Integral b, Integral a, Num c) => b -> a -> c
scale Int
qq)
    | Bool
otherwise    = forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
SV.map (forall {b} {a} {c}. (Integral b, Integral a, Num c) => b -> a -> c
scale Int
q)
          where q :: Int
q = Int
200 forall a. Num a => a -> a -> a
- Int
quality forall a. Num a => a -> a -> a
* Int
2
                scale :: b -> a -> c
scale b
coeff a
i = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => a -> a -> a
min b
255 
                                             forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => a -> a -> a
max b
1 
                                             forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i forall a. Num a => a -> a -> a
* b
coeff forall a. Integral a => a -> a -> a
`div` b
100

huffmanPackedDecode :: HuffmanPackedTree -> BoolReader s Word8
huffmanPackedDecode :: forall s. HuffmanPackedTree -> BoolReader s Word8
huffmanPackedDecode HuffmanPackedTree
table = forall s. BoolReader s Bool
getNextBitJpg forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {a} {s}.
Num a =>
Word16 -> Bool -> StateT BoolState (ST s) a
aux Word16
0
  where aux :: Word16 -> Bool -> StateT BoolState (ST s) a
aux Word16
idx Bool
b
            | (Word16
v forall a. Bits a => a -> a -> a
.&. Word16
0x8000) forall a. Eq a => a -> a -> Bool
/= Word16
0 = forall (m :: * -> *) a. Monad m => a -> m a
return  a
0
            | (Word16
v forall a. Bits a => a -> a -> a
.&. Word16
0x4000) forall a. Eq a => a -> a -> Bool
/= Word16
0 = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Word16
v forall a. Bits a => a -> a -> a
.&. Word16
0xFF
            | Bool
otherwise = forall s. BoolReader s Bool
getNextBitJpg forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Word16 -> Bool -> StateT BoolState (ST s) a
aux Word16
v
          where tableIndex :: Word16
tableIndex | Bool
b = Word16
idx forall a. Num a => a -> a -> a
+ Word16
1
                           | Bool
otherwise = Word16
idx
                v :: Word16
v = HuffmanPackedTree
table forall a. Storable a => Vector a -> Int -> a
`SV.unsafeIndex` forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
tableIndex

defaultLumaQuantizationTable :: QuantificationTable
defaultLumaQuantizationTable :: QuantificationTable
defaultLumaQuantizationTable = forall a. Storable a => [a] -> MacroBlock a
makeMacroBlock
    [Int16
16, Int16
11, Int16
10, Int16
16,  Int16
24,  Int16
40,  Int16
51,  Int16
61
    ,Int16
12, Int16
12, Int16
14, Int16
19,  Int16
26,  Int16
58,  Int16
60,  Int16
55
    ,Int16
14, Int16
13, Int16
16, Int16
24,  Int16
40,  Int16
57,  Int16
69,  Int16
56
    ,Int16
14, Int16
17, Int16
22, Int16
29,  Int16
51,  Int16
87,  Int16
80,  Int16
62
    ,Int16
18, Int16
22, Int16
37, Int16
56,  Int16
68, Int16
109, Int16
103,  Int16
77
    ,Int16
24, Int16
35, Int16
55, Int16
64,  Int16
81, Int16
104, Int16
113,  Int16
92
    ,Int16
49, Int16
64, Int16
78, Int16
87, Int16
103, Int16
121, Int16
120, Int16
101
    ,Int16
72, Int16
92, Int16
95, Int16
98, Int16
112, Int16
100, Int16
103,  Int16
99
    ]

defaultChromaQuantizationTable :: QuantificationTable
defaultChromaQuantizationTable :: QuantificationTable
defaultChromaQuantizationTable = forall a. Storable a => [a] -> MacroBlock a
makeMacroBlock
    [Int16
17, Int16
18, Int16
24, Int16
47, Int16
99, Int16
99, Int16
99, Int16
99
    ,Int16
18, Int16
21, Int16
26, Int16
66, Int16
99, Int16
99, Int16
99, Int16
99
    ,Int16
24, Int16
26, Int16
56, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99
    ,Int16
47, Int16
66, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99
    ,Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99
    ,Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99
    ,Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99
    ,Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99, Int16
99
    ]

defaultDcLumaHuffmanTree :: HuffmanTree
defaultDcLumaHuffmanTree :: HuffmanTree
defaultDcLumaHuffmanTree = [[Word8]] -> HuffmanTree
buildHuffmanTree [[Word8]]
defaultDcLumaHuffmanTable

-- | From the Table K.3 of ITU-81 (p153)

defaultDcLumaHuffmanTable :: HuffmanTable
defaultDcLumaHuffmanTable :: [[Word8]]
defaultDcLumaHuffmanTable =
    [ []
    , [Word8
0]
    , [Word8
1, Word8
2, Word8
3, Word8
4, Word8
5]
    , [Word8
6]
    , [Word8
7]
    , [Word8
8]
    , [Word8
9]
    , [Word8
10]
    , [Word8
11]
    , []
    , []
    , []
    , []
    , []
    , []
    , []
    ]

defaultDcChromaHuffmanTree :: HuffmanTree
defaultDcChromaHuffmanTree :: HuffmanTree
defaultDcChromaHuffmanTree = [[Word8]] -> HuffmanTree
buildHuffmanTree [[Word8]]
defaultDcChromaHuffmanTable

-- | From the Table K.4 of ITU-81 (p153)

defaultDcChromaHuffmanTable :: HuffmanTable
defaultDcChromaHuffmanTable :: [[Word8]]
defaultDcChromaHuffmanTable = 
    [ []
    , [Word8
0, Word8
1, Word8
2]
    , [Word8
3]
    , [Word8
4]
    , [Word8
5]
    , [Word8
6]
    , [Word8
7]
    , [Word8
8]
    , [Word8
9]
    , [Word8
10]
    , [Word8
11]
    , []
    , []
    , []
    , []
    , []
    ]

defaultAcLumaHuffmanTree :: HuffmanTree
defaultAcLumaHuffmanTree :: HuffmanTree
defaultAcLumaHuffmanTree = [[Word8]] -> HuffmanTree
buildHuffmanTree [[Word8]]
defaultAcLumaHuffmanTable

-- | From the Table K.5 of ITU-81 (p154)

defaultAcLumaHuffmanTable :: HuffmanTable
defaultAcLumaHuffmanTable :: [[Word8]]
defaultAcLumaHuffmanTable =
    [ []
    , [Word8
0x01, Word8
0x02]
    , [Word8
0x03]
    , [Word8
0x00, Word8
0x04, Word8
0x11]
    , [Word8
0x05, Word8
0x12, Word8
0x21]
    , [Word8
0x31, Word8
0x41]
    , [Word8
0x06, Word8
0x13, Word8
0x51, Word8
0x61]
    , [Word8
0x07, Word8
0x22, Word8
0x71]
    , [Word8
0x14, Word8
0x32, Word8
0x81, Word8
0x91, Word8
0xA1]
    , [Word8
0x08, Word8
0x23, Word8
0x42, Word8
0xB1, Word8
0xC1]
    , [Word8
0x15, Word8
0x52, Word8
0xD1, Word8
0xF0]
    , [Word8
0x24, Word8
0x33, Word8
0x62, Word8
0x72]
    , []
    , []
    , [Word8
0x82]
    , [Word8
0x09, Word8
0x0A, Word8
0x16, Word8
0x17, Word8
0x18, Word8
0x19, Word8
0x1A, Word8
0x25, Word8
0x26, Word8
0x27, Word8
0x28, Word8
0x29, Word8
0x2A, Word8
0x34, Word8
0x35
      ,Word8
0x36, Word8
0x37, Word8
0x38, Word8
0x39, Word8
0x3A, Word8
0x43, Word8
0x44, Word8
0x45, Word8
0x46, Word8
0x47, Word8
0x48, Word8
0x49, Word8
0x4A, Word8
0x53, Word8
0x54
      ,Word8
0x55, Word8
0x56, Word8
0x57, Word8
0x58, Word8
0x59, Word8
0x5A, Word8
0x63, Word8
0x64, Word8
0x65, Word8
0x66, Word8
0x67, Word8
0x68, Word8
0x69, Word8
0x6A, Word8
0x73
      ,Word8
0x74, Word8
0x75, Word8
0x76, Word8
0x77, Word8
0x78, Word8
0x79, Word8
0x7A, Word8
0x83, Word8
0x84, Word8
0x85, Word8
0x86, Word8
0x87, Word8
0x88, Word8
0x89, Word8
0x8A
      ,Word8
0x92, Word8
0x93, Word8
0x94, Word8
0x95, Word8
0x96, Word8
0x97, Word8
0x98, Word8
0x99, Word8
0x9A, Word8
0xA2, Word8
0xA3, Word8
0xA4, Word8
0xA5, Word8
0xA6, Word8
0xA7
      ,Word8
0xA8, Word8
0xA9, Word8
0xAA, Word8
0xB2, Word8
0xB3, Word8
0xB4, Word8
0xB5, Word8
0xB6, Word8
0xB7, Word8
0xB8, Word8
0xB9, Word8
0xBA, Word8
0xC2, Word8
0xC3, Word8
0xC4
      ,Word8
0xC5, Word8
0xC6, Word8
0xC7, Word8
0xC8, Word8
0xC9, Word8
0xCA, Word8
0xD2, Word8
0xD3, Word8
0xD4, Word8
0xD5, Word8
0xD6, Word8
0xD7, Word8
0xD8, Word8
0xD9, Word8
0xDA
      ,Word8
0xE1, Word8
0xE2, Word8
0xE3, Word8
0xE4, Word8
0xE5, Word8
0xE6, Word8
0xE7, Word8
0xE8, Word8
0xE9, Word8
0xEA, Word8
0xF1, Word8
0xF2, Word8
0xF3, Word8
0xF4, Word8
0xF5
      ,Word8
0xF6, Word8
0xF7, Word8
0xF8, Word8
0xF9, Word8
0xFA]
    ]

type HuffmanTable = [[Word8]]

defaultAcChromaHuffmanTree :: HuffmanTree
defaultAcChromaHuffmanTree :: HuffmanTree
defaultAcChromaHuffmanTree = [[Word8]] -> HuffmanTree
buildHuffmanTree [[Word8]]
defaultAcChromaHuffmanTable 

defaultAcChromaHuffmanTable :: HuffmanTable
defaultAcChromaHuffmanTable :: [[Word8]]
defaultAcChromaHuffmanTable = 
    [ []
    , [Word8
0x00, Word8
0x01]
    , [Word8
0x02]
    , [Word8
0x03, Word8
0x11]
    , [Word8
0x04, Word8
0x05, Word8
0x21, Word8
0x31]
    , [Word8
0x06, Word8
0x12, Word8
0x41, Word8
0x51]
    , [Word8
0x07, Word8
0x61, Word8
0x71]
    , [Word8
0x13, Word8
0x22, Word8
0x32, Word8
0x81]
    , [Word8
0x08, Word8
0x14, Word8
0x42, Word8
0x91, Word8
0xA1, Word8
0xB1, Word8
0xC1]
    , [Word8
0x09, Word8
0x23, Word8
0x33, Word8
0x52, Word8
0xF0]
    , [Word8
0x15, Word8
0x62, Word8
0x72, Word8
0xD1]
    , [Word8
0x0A, Word8
0x16, Word8
0x24, Word8
0x34]
    , []
    , [Word8
0xE1]
    , [Word8
0x25, Word8
0xF1]
    , [ Word8
0x17, Word8
0x18, Word8
0x19, Word8
0x1A, Word8
0x26, Word8
0x27, Word8
0x28, Word8
0x29, Word8
0x2A, Word8
0x35
      , Word8
0x36, Word8
0x37, Word8
0x38, Word8
0x39, Word8
0x3A, Word8
0x43, Word8
0x44, Word8
0x45, Word8
0x46, Word8
0x47
      , Word8
0x48, Word8
0x49, Word8
0x4A, Word8
0x53, Word8
0x54, Word8
0x55, Word8
0x56, Word8
0x57, Word8
0x58, Word8
0x59
      , Word8
0x5A, Word8
0x63, Word8
0x64, Word8
0x65, Word8
0x66, Word8
0x67, Word8
0x68, Word8
0x69, Word8
0x6A, Word8
0x73
      , Word8
0x74, Word8
0x75, Word8
0x76, Word8
0x77, Word8
0x78, Word8
0x79, Word8
0x7A, Word8
0x82, Word8
0x83, Word8
0x84
      , Word8
0x85, Word8
0x86, Word8
0x87, Word8
0x88, Word8
0x89, Word8
0x8A, Word8
0x92, Word8
0x93, Word8
0x94, Word8
0x95
      , Word8
0x96, Word8
0x97, Word8
0x98, Word8
0x99, Word8
0x9A, Word8
0xA2, Word8
0xA3, Word8
0xA4, Word8
0xA5, Word8
0xA6
      , Word8
0xA7, Word8
0xA8, Word8
0xA9, Word8
0xAA, Word8
0xB2, Word8
0xB3, Word8
0xB4, Word8
0xB5, Word8
0xB6, Word8
0xB7
      , Word8
0xB8, Word8
0xB9, Word8
0xBA, Word8
0xC2, Word8
0xC3, Word8
0xC4, Word8
0xC5, Word8
0xC6, Word8
0xC7, Word8
0xC8
      , Word8
0xC9, Word8
0xCA, Word8
0xD2, Word8
0xD3, Word8
0xD4, Word8
0xD5, Word8
0xD6, Word8
0xD7, Word8
0xD8, Word8
0xD9
      , Word8
0xDA, Word8
0xE2, Word8
0xE3, Word8
0xE4, Word8
0xE5, Word8
0xE6, Word8
0xE7, Word8
0xE8, Word8
0xE9, Word8
0xEA
      , Word8
0xF2, Word8
0xF3, Word8
0xF4, Word8
0xF5, Word8
0xF6, Word8
0xF7, Word8
0xF8, Word8
0xF9, Word8
0xFA
      ]
    ]