    {-# LINE 1 "Graphics/GD.hsc" #-}
    {-# LANGUAGE EmptyDataDecls #-}
    module Graphics.GD (
                        -- * Types
                        Image, Size, Point, Color, PCREOption(..),
                        -- * Creating and copying images
                        newImage, copyImage,
                        copyRegion, copyRegionScaled,
                        -- * Memory management
                        withImage,
                        -- * Loading images
                        -- ** JPEG
                        loadJpegFile, loadJpegData, loadJpegByteString,
                        -- ** PNG
                        loadPngFile, loadPngData, loadPngByteString,
                        -- ** GIF
                        loadGifFile, loadGifData, loadGifByteString,
                        -- * Saving images
                        -- ** JPEG
                        saveJpegFile, saveJpegByteString,
                        -- ** PNG
                        savePngFile, savePngByteString,
                        -- ** GIF
                        saveGifFile, saveGifByteString,
                        -- * Getting image information
                        imageSize,
                        -- * Querying
                        getPixel,
                        -- * Manipulating images
                        resizeImage, rotateImage,
                        -- * Drawing
                        brushed,
                        setBrush,
                        fillImage,
                        drawFilledRectangle,
                        drawFilledEllipse,
                        drawLine,
                        drawArc,
                        antiAliased,
                        setPixel,
                        colorAllocate,
                        -- * Text
                        useFontConfig,
                        drawString, measureString,
                        drawStringCircle,
                        -- * Colors
                        rgb, rgba, toRGBA,
                        -- * Misc
                        saveAlpha,
                        alphaBlending,

                       ) where

    import           Control.Exception        (bracket)
    import           Control.Monad            (liftM, unless)
    import           Data.Bits
    import qualified Data.ByteString.Internal as B
    import           Foreign                  (Ptr,FunPtr,ForeignPtr)
    import           Foreign                  (peekByteOff)
    import qualified Foreign                  as F
    import           Foreign.C                (CString)
    import qualified Foreign.C                as C
    import           Foreign.C.Types

    data CFILE

    foreign import ccall "stdio.h fopen" c_fopen
        :: CString -> CString -> IO (Ptr CFILE)
    foreign import ccall "stdio.h fclose" c_fclose
        :: Ptr CFILE -> IO CInt

    fopen :: FilePath -> String -> IO (Ptr CFILE)
    fopen :: FilePath -> FilePath -> IO (Ptr CFILE)
    fopen FilePath
    file FilePath
    mode =
        FilePath -> IO (Ptr CFILE) -> IO (Ptr CFILE)
    forall a. FilePath -> IO (Ptr a) -> IO (Ptr a)
    C.throwErrnoIfNull FilePath
    file (IO (Ptr CFILE) -> IO (Ptr CFILE))
    -> IO (Ptr CFILE) -> IO (Ptr CFILE)
    forall a b. (a -> b) -> a -> b
    $ FilePath -> (CString -> IO (Ptr CFILE)) -> IO (Ptr CFILE)
    forall a. FilePath -> (CString -> IO a) -> IO a
    C.withCString FilePath
    file ((CString -> IO (Ptr CFILE)) -> IO (Ptr CFILE))
    -> (CString -> IO (Ptr CFILE)) -> IO (Ptr CFILE)
    forall a b. (a -> b) -> a -> b
    $
                             \CString
    f -> FilePath -> (CString -> IO (Ptr CFILE)) -> IO (Ptr CFILE)
    forall a. FilePath -> (CString -> IO a) -> IO a
    C.withCString FilePath
    mode ((CString -> IO (Ptr CFILE)) -> IO (Ptr CFILE))
    -> (CString -> IO (Ptr CFILE)) -> IO (Ptr CFILE)
    forall a b. (a -> b) -> a -> b
    $ \CString
    m -> CString -> CString -> IO (Ptr CFILE)
    c_fopen CString
    f CString
    m

    fclose :: Ptr CFILE -> IO ()
    fclose :: Ptr CFILE -> IO ()
    fclose Ptr CFILE
    p = (Color -> Bool) -> FilePath -> IO Color -> IO ()
    forall a. (a -> Bool) -> FilePath -> IO a -> IO ()
    C.throwErrnoIf_ (Color -> Color -> Bool
    forall a. Eq a => a -> a -> Bool
    == -Color
    1) FilePath
    "fclose" (IO Color -> IO ()) -> IO Color -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Ptr CFILE -> IO Color
    c_fclose Ptr CFILE
    p
    {-# LINE 78 "Graphics/GD.hsc" #-}

    withCFILE :: FilePath -> String -> (Ptr CFILE -> IO a) -> IO a
    withCFILE :: forall a. FilePath -> FilePath -> (Ptr CFILE -> IO a) -> IO a
    withCFILE FilePath
    file FilePath
    mode = IO (Ptr CFILE)
    -> (Ptr CFILE -> IO ()) -> (Ptr CFILE -> IO a) -> IO a
    forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
    bracket (FilePath -> FilePath -> IO (Ptr CFILE)
    fopen FilePath
    file FilePath
    mode) Ptr CFILE -> IO ()
    fclose

    data GDImage

    -- JPEG format

    foreign import ccall "gd.h gdImageCreateFromJpeg" gdImageCreateFromJpeg
        :: Ptr CFILE -> IO (Ptr GDImage)

    foreign import ccall "gd.h gdImageCreateFromJpegPtr" gdImageCreateFromJpegPtr
        :: CInt -> Ptr a -> IO (Ptr GDImage)

    foreign import ccall "gd.h gdImageJpeg" gdImageJpeg
        :: Ptr GDImage -> Ptr CFILE -> CInt -> IO ()

    foreign import ccall "gd.h gdImageJpegPtr" gdImageJpegPtr
        :: Ptr GDImage -> Ptr CInt -> CInt -> IO (Ptr a)

    -- PNG format

    foreign import ccall "gd.h gdImageCreateFromPng" gdImageCreateFromPng
        :: Ptr CFILE -> IO (Ptr GDImage)

    foreign import ccall "gd.h gdImageCreateFromPngPtr" gdImageCreateFromPngPtr
        :: CInt -> Ptr a -> IO (Ptr GDImage)

    foreign import ccall "gd.h gdImagePng" gdImagePng
        :: Ptr GDImage -> Ptr CFILE -> IO ()

    foreign import ccall "gd.h gdImagePngPtr" gdImagePngPtr
        :: Ptr GDImage -> Ptr CInt -> IO (Ptr a)

    -- GIF format

    foreign import ccall "gd.h gdImageCreateFromGif" gdImageCreateFromGif
        :: Ptr CFILE -> IO (Ptr GDImage)

    foreign import ccall "gd.h gdImageCreateFromGifPtr" gdImageCreateFromGifPtr
        :: CInt -> Ptr a -> IO (Ptr GDImage)

    foreign import ccall "gd.h gdImageGif" gdImageGif
        :: Ptr GDImage -> Ptr CFILE -> IO ()

    foreign import ccall "gd.h gdImageGifPtr" gdImageGifPtr
        :: Ptr GDImage -> Ptr CInt -> IO (Ptr a)

    -- Creating and destroying images

    foreign import ccall "gd.h gdImageCreateTrueColor" gdImageCreateTrueColor
        :: CInt -> CInt -> IO (Ptr GDImage)

    foreign import ccall "gd.h gdImageDestroy" gdImageDestroy
        :: Ptr GDImage -> IO ()

    foreign import ccall "gd-extras.h &gdImagePtrDestroyIfNotNull"
            ptr_gdImagePtrDestroyIfNotNull
        :: FunPtr (Ptr (Ptr GDImage) -> IO ())

    -- Copying image parts

    foreign import ccall "gd.h gdImageCopy" gdImageCopy
        :: Ptr GDImage -> Ptr GDImage
        -> CInt -> CInt -> CInt -> CInt
        -> CInt -> CInt -> IO ()

    foreign import ccall "gd.h gdImageCopyResampled" gdImageCopyResampled
        :: Ptr GDImage -> Ptr GDImage
        -> CInt -> CInt -> CInt -> CInt
        -> CInt -> CInt -> CInt -> CInt -> IO ()

    {-
    foreign import ccall "gd.h gdImageCopyRotated" gdImageCopyRotated
        :: Ptr GDImage -> Ptr GDImage
        -> CDouble -> CDouble -> CInt -> CInt
        -> CInt -> CInt -> CInt -> IO ()
    -}

    foreign import ccall "gd-extras.h gdImageCopyRotated90" gdImageCopyRotated90
        :: Ptr GDImage -> Ptr GDImage
        -> CInt -> CInt -> CInt -> CInt
        -> CInt -> CInt -> CInt -> IO ()

    foreign import ccall "gd.h gdImageGetPixel" gdImageGetPixel
        :: Ptr GDImage -> CInt -> CInt -> IO CInt

    -- Drawing functions

    foreign import ccall "gd.h gdImageSetBrush" gdImageSetBrush
        :: Ptr GDImage -> Ptr GDImage -> IO ()

    foreign import ccall "gd.h gdImageFilledRectangle" gdImageFilledRectangle
        :: Ptr GDImage -> CInt -> CInt -> CInt -> CInt -> CInt -> IO ()

    foreign import ccall "gd.h gdImageFilledEllipse" gdImageFilledEllipse
        :: Ptr GDImage -> CInt -> CInt -> CInt -> CInt -> CInt -> IO ()

    foreign import ccall "gd.h gdImageLine" gdImageLine
        :: Ptr GDImage -> CInt -> CInt -> CInt -> CInt -> CInt -> IO ()

    foreign import ccall "gd.h gdImageArc" gdImageArc
        :: Ptr GDImage -> CInt -> CInt -> CInt -> CInt
        -> CInt -> CInt -> CInt -> IO ()

    foreign import ccall "gd.h gdImageSetAntiAliased" gdImageSetAntiAliased
        :: Ptr GDImage -> CInt -> IO ()

    foreign import ccall "gd.h gdImageSetPixel" gdImageSetPixel
        :: Ptr GDImage -> CInt -> CInt -> CInt -> IO ()

    foreign import ccall "gd.h gdImageColorAllocate" gdImageColorAllocate
        :: Ptr GDImage -> CInt -> CInt -> CInt -> CInt -> IO CInt

    -- Text functions

    foreign import ccall "gd.h gdFTUseFontConfig" gdFTUseFontConfig
        :: CInt -> IO CInt

    foreign import ccall "gd.h gdImageStringFT" gdImageStringFT
        :: Ptr GDImage -> Ptr CInt -> CInt -> CString -> CDouble -> CDouble ->
           CInt -> CInt -> CString -> IO CString

    foreign import ccall "gd.h gdImageStringFTCircle" gdImageStringFTCircle
        :: Ptr GDImage -> CInt -> CInt -> CDouble -> CDouble -> CDouble -> CString
           -> CDouble -> CString -> CString -> CInt -> IO CString

    -- Miscellaneous functions

    foreign import ccall "gd.h &gdFree" gdFree
        :: FunPtr (Ptr a -> IO ())

    toRGBA :: Color -> (Int, Int, Int, Int)
    toRGBA :: Color -> (Int, Int, Int, Int)
    toRGBA Color
    c = (Color -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Color
    r, Color -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Color
    g, Color -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Color
    b, Color -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Color
    a)
     where
       b :: Color
    b = Color
    c Color -> Color -> Color
    forall a. Integral a => a -> a -> a
    `mod` Color
    byte
       g :: Color
    g = Color -> Int -> Color
    forall a. Bits a => a -> Int -> a
    shiftR Color
    c Int
    8 Color -> Color -> Color
    forall a. Integral a => a -> a -> a
    `mod` Color
    byte
       r :: Color
    r = Color -> Int -> Color
    forall a. Bits a => a -> Int -> a
    shiftR Color
    c Int
    16 Color -> Color -> Color
    forall a. Integral a => a -> a -> a
    `mod` Color
    byte
       a :: Color
    a = Color -> Int -> Color
    forall a. Bits a => a -> Int -> a
    shiftR Color
    c Int
    24 Color -> Color -> Color
    forall a. Integral a => a -> a -> a
    `mod` Color
    byte
       byte :: Color
    byte = Color
    2 Color -> Int -> Color
    forall a b. (Num a, Integral b) => a -> b -> a
    ^ (Int
    8::Int)

    foreign import ccall "gd.h gdImageSaveAlpha" gdImageSaveAlpha
        :: Ptr GDImage -> CInt -> IO ()

    foreign import ccall "gd.h gdImageAlphaBlending" gdImageAlphaBlending
        :: Ptr GDImage -> CInt -> IO ()

    -- | To access the definition 'gdBrush' from GD
    newtype PCREOption = PCREOption { PCREOption -> Color
    unPCREOption :: CInt }
        deriving (PCREOption -> PCREOption -> Bool
    (PCREOption -> PCREOption -> Bool)
    -> (PCREOption -> PCREOption -> Bool) -> Eq PCREOption
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PCREOption -> PCREOption -> Bool
    == :: PCREOption -> PCREOption -> Bool
    $c/= :: PCREOption -> PCREOption -> Bool
    /= :: PCREOption -> PCREOption -> Bool
    Eq,Int -> PCREOption -> ShowS
    [PCREOption] -> ShowS
    PCREOption -> FilePath
    (Int -> PCREOption -> ShowS)
    -> (PCREOption -> FilePath)
    -> ([PCREOption] -> ShowS)
    -> Show PCREOption
    forall a.
    (Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PCREOption -> ShowS
    showsPrec :: Int -> PCREOption -> ShowS
    $cshow :: PCREOption -> FilePath
    show :: PCREOption -> FilePath
    $cshowList :: [PCREOption] -> ShowS
    showList :: [PCREOption] -> ShowS
    Show)

    -- We use a second level of indirection to allow storing a null pointer
    -- when the image has already been freed. This allows 'withImage' to
    -- free the @gdImage@ early.
    newtype Image = Image (ForeignPtr (Ptr GDImage))

    type Size = (Int,Int)

    type Point = (Int,Int)

    type Color = CInt

    mkImage :: Ptr GDImage -> IO Image
    mkImage :: Ptr GDImage -> IO Image
    mkImage Ptr GDImage
    img = do fp <- IO (ForeignPtr (Ptr GDImage))
    forall a. Storable a => IO (ForeignPtr a)
    F.mallocForeignPtr
                     F.withForeignPtr fp $ \Ptr (Ptr GDImage)
    p -> Ptr (Ptr GDImage) -> Ptr GDImage -> IO ()
    forall a. Storable a => Ptr a -> a -> IO ()
    F.poke Ptr (Ptr GDImage)
    p Ptr GDImage
    img
                     F.addForeignPtrFinalizer ptr_gdImagePtrDestroyIfNotNull fp
                     return $ Image fp

    -- | Creates an image, performs an operation on the image, and
    -- frees it.
    -- This function allows block scoped management of 'Image'
    -- objects.  If you are handling large images, the delay before
    -- the finalizer which frees the image runs may cause significant
    -- temporary extra memory use.  Use this function to force the
    -- image to be freed as soons as you are done with it.  Note that
    -- it is unsafe to hold on to the 'Image' after the function is
    -- done.
    withImage :: IO Image        -- ^ Image creation action.
              -> (Image -> IO b) -- ^ Some operation on the image. The result should
                                 -- not reference the 'Image'.
              -> IO b
    withImage :: forall b. IO Image -> (Image -> IO b) -> IO b
    withImage IO Image
    ini Image -> IO b
    f = IO Image -> (Image -> IO ()) -> (Image -> IO b) -> IO b
    forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
    bracket IO Image
    ini Image -> IO ()
    freeImage Image -> IO b
    f

    -- | Overwrites the pointer with a null pointer, and frees the @gdImage@.
    -- Safe to call twice. Doesn't free the 'ForeignPtr', we rely on the
    -- GC to do that.
    freeImage :: Image -> IO ()
    freeImage :: Image -> IO ()
    freeImage (Image ForeignPtr (Ptr GDImage)
    fp) = ForeignPtr (Ptr GDImage) -> (Ptr (Ptr GDImage) -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    F.withForeignPtr ForeignPtr (Ptr GDImage)
    fp ((Ptr (Ptr GDImage) -> IO ()) -> IO ())
    -> (Ptr (Ptr GDImage) -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $
      \Ptr (Ptr GDImage)
    pp -> do p <- Ptr (Ptr GDImage) -> IO (Ptr GDImage)
    forall a. Storable a => Ptr a -> IO a
    F.peek Ptr (Ptr GDImage)
    pp
                F.poke pp F.nullPtr
                unless (p == F.nullPtr) $ gdImageDestroy p

    withImagePtr :: Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr :: forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr (Image ForeignPtr (Ptr GDImage)
    fp) Ptr GDImage -> IO a
    f = ForeignPtr (Ptr GDImage) -> (Ptr (Ptr GDImage) -> IO a) -> IO a
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    F.withForeignPtr ForeignPtr (Ptr GDImage)
    fp ((Ptr (Ptr GDImage) -> IO a) -> IO a)
    -> (Ptr (Ptr GDImage) -> IO a) -> IO a
    forall a b. (a -> b) -> a -> b
    $
      \Ptr (Ptr GDImage)
    pp -> Ptr (Ptr GDImage) -> IO (Ptr GDImage)
    forall a. Storable a => Ptr a -> IO a
    F.peek Ptr (Ptr GDImage)
    pp IO (Ptr GDImage) -> (Ptr GDImage -> IO a) -> IO a
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \Ptr GDImage
    p ->
           if Ptr GDImage
    p Ptr GDImage -> Ptr GDImage -> Bool
    forall a. Eq a => a -> a -> Bool
    == Ptr GDImage
    forall a. Ptr a
    F.nullPtr then FilePath -> IO a
    forall a. FilePath -> IO a
    forall (m :: * -> *) a. MonadFail m => FilePath -> m a
    fail FilePath
    "Image has been freed." else Ptr GDImage -> IO a
    f Ptr GDImage
    p

    -- | Create a new empty image.
    newImage :: Size -> IO Image
    newImage :: Size -> IO Image
    newImage (Int
    w,Int
    h) = Color -> Color -> IO Image
    newImage_ (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    w) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    h)

    newImage_  :: CInt -> CInt -> IO Image
    newImage_ :: Color -> Color -> IO Image
    newImage_ Color
    w Color
    h = do p <- FilePath -> IO (Ptr GDImage) -> IO (Ptr GDImage)
    forall a. FilePath -> IO (Ptr a) -> IO (Ptr a)
    F.throwIfNull FilePath
    "gdImageCreateTrueColor" (IO (Ptr GDImage) -> IO (Ptr GDImage))
    -> IO (Ptr GDImage) -> IO (Ptr GDImage)
    forall a b. (a -> b) -> a -> b
    $
                            Color -> Color -> IO (Ptr GDImage)
    gdImageCreateTrueColor Color
    w Color
    h
                       mkImage p

    -- | Create a new empty image and apply a function to it.
    onNewImage :: CInt -> CInt -> (Ptr GDImage -> IO a) -> IO Image
    onNewImage :: forall a. Color -> Color -> (Ptr GDImage -> IO a) -> IO Image
    onNewImage Color
    w Color
    h Ptr GDImage -> IO a
    f = Color -> Color -> IO Image
    newImage_ Color
    w Color
    h IO Image -> (Image -> IO Image) -> IO Image
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \Image
    i -> Image -> (Ptr GDImage -> IO a) -> IO a
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i Ptr GDImage -> IO a
    f IO a -> IO Image -> IO Image
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Image -> IO Image
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Image
    i

    -- | Make a copy of an image.
    copyImage :: Image -> IO Image
    copyImage :: Image -> IO Image
    copyImage Image
    i = Image -> (Ptr GDImage -> IO Image) -> IO Image
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i Ptr GDImage -> IO Image
    f
      where f :: Ptr GDImage -> IO Image
    f Ptr GDImage
    p = do (w,h) <- Ptr GDImage -> IO (Color, Color)
    imageSize_ Ptr GDImage
    p
                     onNewImage w h (\Ptr GDImage
    p' -> Ptr GDImage
    -> Ptr GDImage
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> IO ()
    gdImageCopy Ptr GDImage
    p' Ptr GDImage
    p Color
    0 Color
    0 Color
    0 Color
    0 Color
    w Color
    h)

    -- | Copy a region of one image into another
    copyRegion :: Point    -- ^ Source upper left-hand corner
                  -> Size  -- ^ Size of copied region
                  -> Image -- ^ Source image
                  -> Point -- ^ Destination upper left-hand corner
                  -> Image -- ^ Destination image
                  -> IO ()
    copyRegion :: Size -> Size -> Image -> Size -> Image -> IO ()
    copyRegion (Int
    srcX, Int
    srcY) (Int
    w, Int
    h) Image
    srcIPtr (Int
    dstX, Int
    dstY) Image
    dstIPtr
        = Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    dstIPtr ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          \Ptr GDImage
    dstImg -> Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    srcIPtr ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          \Ptr GDImage
    srcImg -> Ptr GDImage
    -> Ptr GDImage
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> IO ()
    gdImageCopy Ptr GDImage
    dstImg Ptr GDImage
    srcImg
                        (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    dstX) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    dstY) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    srcX) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    srcY) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    w) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    h)

    -- | Copy a region of one image into another, rescaling the region
    copyRegionScaled :: Point -- ^ Source upper left-hand corner
                     -> Size  -- ^ Size of source region
                     -> Image -- ^ Source image
                     -> Point -- ^ Destination upper left-hand corner
                     -> Size  -- ^ Size of destination region
                     -> Image -- ^ Destination image
                     -> IO ()
    copyRegionScaled :: Size -> Size -> Image -> Size -> Size -> Image -> IO ()
    copyRegionScaled (Int
    srcX,Int
    srcY) (Int
    srcW,Int
    srcH) Image
    srcIPtr (Int
    dstX,Int
    dstY) (Int
    dstW,Int
    dstH) Image
    dstIPtr
        = Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    dstIPtr ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          \Ptr GDImage
    dstImg -> Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    srcIPtr ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          \Ptr GDImage
    srcImg -> Ptr GDImage
    -> Ptr GDImage
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> IO ()
    gdImageCopyResampled Ptr GDImage
    dstImg Ptr GDImage
    srcImg
                       (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    dstX) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    dstY) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    srcX) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    srcY)
                       (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    dstW) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    dstH) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    srcW) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    srcH)

    --
    -- * Loading images
    --

    -- | Load a JPEG image from a file.
    loadJpegFile :: FilePath -> IO Image
    loadJpegFile :: FilePath -> IO Image
    loadJpegFile = (Ptr CFILE -> IO (Ptr GDImage)) -> FilePath -> IO Image
    loadImageFile Ptr CFILE -> IO (Ptr GDImage)
    gdImageCreateFromJpeg

    -- | Load a JPEG image from a buffer.
    loadJpegData :: Int   -- ^ Buffer size.
                 -> Ptr a -- ^ Buffer with image data.
                 -> IO Image
    loadJpegData :: forall a. Int -> Ptr a -> IO Image
    loadJpegData = (Color -> Ptr a -> IO (Ptr GDImage)) -> Int -> Ptr a -> IO Image
    forall a.
    (Color -> Ptr a -> IO (Ptr GDImage)) -> Int -> Ptr a -> IO Image
    loadImageData Color -> Ptr a -> IO (Ptr GDImage)
    forall a. Color -> Ptr a -> IO (Ptr GDImage)
    gdImageCreateFromJpegPtr

    -- | Load a JPEG image from a ByteString
    loadJpegByteString :: B.ByteString -> IO Image
    loadJpegByteString :: ByteString -> IO Image
    loadJpegByteString = (Int -> Ptr (ZonkAny 3) -> IO Image) -> ByteString -> IO Image
    forall a b. (Int -> Ptr a -> IO b) -> ByteString -> IO b
    onByteStringData Int -> Ptr (ZonkAny 3) -> IO Image
    forall a. Int -> Ptr a -> IO Image
    loadJpegData

    -- | Load a PNG image from a file.
    loadPngFile :: FilePath -> IO Image
    loadPngFile :: FilePath -> IO Image
    loadPngFile = (Ptr CFILE -> IO (Ptr GDImage)) -> FilePath -> IO Image
    loadImageFile Ptr CFILE -> IO (Ptr GDImage)
    gdImageCreateFromPng

    -- | Load a PNG image from a buffer.
    loadPngData :: Int   -- ^ Buffer size.
                -> Ptr a -- ^ Buffer with image data.
                -> IO Image
    loadPngData :: forall a. Int -> Ptr a -> IO Image
    loadPngData = (Color -> Ptr a -> IO (Ptr GDImage)) -> Int -> Ptr a -> IO Image
    forall a.
    (Color -> Ptr a -> IO (Ptr GDImage)) -> Int -> Ptr a -> IO Image
    loadImageData Color -> Ptr a -> IO (Ptr GDImage)
    forall a. Color -> Ptr a -> IO (Ptr GDImage)
    gdImageCreateFromPngPtr

    -- | Load a PNG image from a ByteString
    loadPngByteString :: B.ByteString -> IO Image
    loadPngByteString :: ByteString -> IO Image
    loadPngByteString = (Int -> Ptr (ZonkAny 4) -> IO Image) -> ByteString -> IO Image
    forall a b. (Int -> Ptr a -> IO b) -> ByteString -> IO b
    onByteStringData Int -> Ptr (ZonkAny 4) -> IO Image
    forall a. Int -> Ptr a -> IO Image
    loadPngData

    -- | Load a GIF image from a file.
    loadGifFile :: FilePath -> IO Image
    loadGifFile :: FilePath -> IO Image
    loadGifFile = (Ptr CFILE -> IO (Ptr GDImage)) -> FilePath -> IO Image
    loadImageFile Ptr CFILE -> IO (Ptr GDImage)
    gdImageCreateFromGif

    -- | Load a GIF image from a buffer.
    loadGifData :: Int   -- ^ Buffer size.
                -> Ptr a -- ^ Buffer with image data.
                -> IO Image
    loadGifData :: forall a. Int -> Ptr a -> IO Image
    loadGifData = (Color -> Ptr a -> IO (Ptr GDImage)) -> Int -> Ptr a -> IO Image
    forall a.
    (Color -> Ptr a -> IO (Ptr GDImage)) -> Int -> Ptr a -> IO Image
    loadImageData Color -> Ptr a -> IO (Ptr GDImage)
    forall a. Color -> Ptr a -> IO (Ptr GDImage)
    gdImageCreateFromGifPtr

    -- | Load a GIF image from a ByteString
    loadGifByteString :: B.ByteString -> IO Image
    loadGifByteString :: ByteString -> IO Image
    loadGifByteString = (Int -> Ptr (ZonkAny 5) -> IO Image) -> ByteString -> IO Image
    forall a b. (Int -> Ptr a -> IO b) -> ByteString -> IO b
    onByteStringData Int -> Ptr (ZonkAny 5) -> IO Image
    forall a. Int -> Ptr a -> IO Image
    loadGifData

    loadImageFile :: (Ptr CFILE -> IO (Ptr GDImage)) -> FilePath -> IO Image
    loadImageFile :: (Ptr CFILE -> IO (Ptr GDImage)) -> FilePath -> IO Image
    loadImageFile Ptr CFILE -> IO (Ptr GDImage)
    f FilePath
    file = do
        p <- FilePath -> IO (Ptr GDImage) -> IO (Ptr GDImage)
    forall a. FilePath -> IO (Ptr a) -> IO (Ptr a)
    F.throwIfNull (FilePath
    "Loading image from " FilePath -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    file) (IO (Ptr GDImage) -> IO (Ptr GDImage))
    -> IO (Ptr GDImage) -> IO (Ptr GDImage)
    forall a b. (a -> b) -> a -> b
    $ FilePath
    -> FilePath -> (Ptr CFILE -> IO (Ptr GDImage)) -> IO (Ptr GDImage)
    forall a. FilePath -> FilePath -> (Ptr CFILE -> IO a) -> IO a
    withCFILE FilePath
    file FilePath
    "rb" Ptr CFILE -> IO (Ptr GDImage)
    f
        mkImage p

    loadImageData :: (CInt -> Ptr a -> IO (Ptr GDImage)) -> Int -> Ptr a -> IO Image
    loadImageData :: forall a.
    (Color -> Ptr a -> IO (Ptr GDImage)) -> Int -> Ptr a -> IO Image
    loadImageData Color -> Ptr a -> IO (Ptr GDImage)
    f Int
    sz Ptr a
    buf = do
        p <- FilePath -> IO (Ptr GDImage) -> IO (Ptr GDImage)
    forall a. FilePath -> IO (Ptr a) -> IO (Ptr a)
    F.throwIfNull (FilePath
    "Loading image") (IO (Ptr GDImage) -> IO (Ptr GDImage))
    -> IO (Ptr GDImage) -> IO (Ptr GDImage)
    forall a b. (a -> b) -> a -> b
    $ Color -> Ptr a -> IO (Ptr GDImage)
    f (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    sz) Ptr a
    buf
        mkImage p

    onByteStringData :: (Int -> Ptr a -> IO b) -> B.ByteString -> IO b
    onByteStringData :: forall a b. (Int -> Ptr a -> IO b) -> ByteString -> IO b
    onByteStringData Int -> Ptr a -> IO b
    f ByteString
    bstr =
        case ByteString -> (ForeignPtr Word8, Int, Int)
    B.toForeignPtr ByteString
    bstr of
          (ForeignPtr Word8
    fptr, Int
    start, Int
    sz) -> ForeignPtr Word8 -> (Ptr Word8 -> IO b) -> IO b
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    F.withForeignPtr ForeignPtr Word8
    fptr ((Ptr Word8 -> IO b) -> IO b) -> (Ptr Word8 -> IO b) -> IO b
    forall a b. (a -> b) -> a -> b
    $
                               \Ptr Word8
    ptr -> Int -> Ptr a -> IO b
    f Int
    sz (Ptr Word8 -> Int -> Ptr a
    forall a b. Ptr a -> Int -> Ptr b
    F.plusPtr Ptr Word8
    ptr Int
    start)

    --
    -- * Saving images
    --

    -- | Save an image as a JPEG file.
    saveJpegFile :: Int -- ^ quality: 0-95, or negative for default quality.
                 -> FilePath -> Image -> IO ()
    saveJpegFile :: Int -> FilePath -> Image -> IO ()
    saveJpegFile Int
    q = (Ptr GDImage -> Ptr CFILE -> IO ()) -> FilePath -> Image -> IO ()
    saveImageFile (\Ptr GDImage
    p Ptr CFILE
    h -> Ptr GDImage -> Ptr CFILE -> Color -> IO ()
    gdImageJpeg Ptr GDImage
    p Ptr CFILE
    h (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    q))

    -- | Write a JPEG format ByteString of an image.
    saveJpegByteString :: Int -> Image -> IO B.ByteString
    saveJpegByteString :: Int -> Image -> IO ByteString
    saveJpegByteString Int
    q =
      (Ptr GDImage -> Ptr Color -> IO (Ptr (ZonkAny 0)))
    -> Image -> IO ByteString
    forall a.
    (Ptr GDImage -> Ptr Color -> IO (Ptr a)) -> Image -> IO ByteString
    saveImageByteString (\Ptr GDImage
    p Ptr Color
    h -> Ptr GDImage -> Ptr Color -> Color -> IO (Ptr (ZonkAny 0))
    forall a. Ptr GDImage -> Ptr Color -> Color -> IO (Ptr a)
    gdImageJpegPtr Ptr GDImage
    p Ptr Color
    h (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    q))

    -- | Save an image as a PNG file.
    savePngFile :: FilePath -> Image -> IO ()
    savePngFile :: FilePath -> Image -> IO ()
    savePngFile = (Ptr GDImage -> Ptr CFILE -> IO ()) -> FilePath -> Image -> IO ()
    saveImageFile Ptr GDImage -> Ptr CFILE -> IO ()
    gdImagePng

    -- | Write a PNG format ByteString of an image.
    savePngByteString :: Image -> IO B.ByteString
    savePngByteString :: Image -> IO ByteString
    savePngByteString = (Ptr GDImage -> Ptr Color -> IO (Ptr (ZonkAny 1)))
    -> Image -> IO ByteString
    forall a.
    (Ptr GDImage -> Ptr Color -> IO (Ptr a)) -> Image -> IO ByteString
    saveImageByteString Ptr GDImage -> Ptr Color -> IO (Ptr (ZonkAny 1))
    forall a. Ptr GDImage -> Ptr Color -> IO (Ptr a)
    gdImagePngPtr

    -- | Save an image as a GIF file.
    saveGifFile :: FilePath -> Image -> IO ()
    saveGifFile :: FilePath -> Image -> IO ()
    saveGifFile = (Ptr GDImage -> Ptr CFILE -> IO ()) -> FilePath -> Image -> IO ()
    saveImageFile Ptr GDImage -> Ptr CFILE -> IO ()
    gdImageGif

    -- | Write a GIF format ByteString of an image.
    saveGifByteString :: Image -> IO B.ByteString
    saveGifByteString :: Image -> IO ByteString
    saveGifByteString = (Ptr GDImage -> Ptr Color -> IO (Ptr (ZonkAny 2)))
    -> Image -> IO ByteString
    forall a.
    (Ptr GDImage -> Ptr Color -> IO (Ptr a)) -> Image -> IO ByteString
    saveImageByteString Ptr GDImage -> Ptr Color -> IO (Ptr (ZonkAny 2))
    forall a. Ptr GDImage -> Ptr Color -> IO (Ptr a)
    gdImageGifPtr

    saveImageFile :: (Ptr GDImage -> Ptr CFILE -> IO ())
                     -> FilePath -> Image -> IO ()
    saveImageFile :: (Ptr GDImage -> Ptr CFILE -> IO ()) -> FilePath -> Image -> IO ()
    saveImageFile Ptr GDImage -> Ptr CFILE -> IO ()
    f FilePath
    file Image
    i = Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i (\Ptr GDImage
    p -> FilePath -> FilePath -> (Ptr CFILE -> IO ()) -> IO ()
    forall a. FilePath -> FilePath -> (Ptr CFILE -> IO a) -> IO a
    withCFILE FilePath
    file FilePath
    "wb" (Ptr GDImage -> Ptr CFILE -> IO ()
    f Ptr GDImage
    p))

    saveImageByteString :: (Ptr GDImage -> Ptr CInt -> IO (Ptr a)) -> Image
                           -> IO (B.ByteString)
    saveImageByteString :: forall a.
    (Ptr GDImage -> Ptr Color -> IO (Ptr a)) -> Image -> IO ByteString
    saveImageByteString Ptr GDImage -> Ptr Color -> IO (Ptr a)
    f Image
    img = Image -> (Ptr GDImage -> IO ByteString) -> IO ByteString
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    img (\Ptr GDImage
    p -> (Ptr Color -> IO (Ptr a)) -> IO ByteString
    forall a. (Ptr Color -> IO (Ptr a)) -> IO ByteString
    dataByteString (Ptr GDImage -> Ptr Color -> IO (Ptr a)
    f Ptr GDImage
    p))

    dataByteString :: (Ptr CInt -> IO (Ptr a)) -> IO B.ByteString
    dataByteString :: forall a. (Ptr Color -> IO (Ptr a)) -> IO ByteString
    dataByteString Ptr Color -> IO (Ptr a)
    f = (Ptr Color -> IO ByteString) -> IO ByteString
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    F.alloca ((Ptr Color -> IO ByteString) -> IO ByteString)
    -> (Ptr Color -> IO ByteString) -> IO ByteString
    forall a b. (a -> b) -> a -> b
    $ \Ptr Color
    szPtr -> do
        datPtr <- Ptr Color -> IO (Ptr a)
    f Ptr Color
    szPtr IO (Ptr a)
    -> (Ptr a -> IO (ForeignPtr Word8)) -> IO (ForeignPtr Word8)
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= FinalizerPtr Word8 -> Ptr Word8 -> IO (ForeignPtr Word8)
    forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
    F.newForeignPtr FinalizerPtr Word8
    forall a. FunPtr (Ptr a -> IO ())
    gdFree (Ptr Word8 -> IO (ForeignPtr Word8))
    -> (Ptr a -> Ptr Word8) -> Ptr a -> IO (ForeignPtr Word8)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Ptr a -> Ptr Word8
    forall a b. Ptr a -> Ptr b
    F.castPtr
        liftM (B.fromForeignPtr datPtr 0 . fromIntegral) (F.peek szPtr)

    --
    -- * Querying
    --

    -- | Retrieves the color index or the color values of a particular pixel.
    getPixel :: (Int,Int) -> Image -> IO Color
    getPixel :: Size -> Image -> IO Color
    getPixel (Int
    x,Int
    y) Image
    i = Image -> (Ptr GDImage -> IO Color) -> IO Color
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i Ptr GDImage -> IO Color
    f
        where f :: Ptr GDImage -> IO Color
    f Ptr GDImage
    p' = Ptr GDImage -> Color -> Color -> IO Color
    gdImageGetPixel Ptr GDImage
    p' (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    x) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    y)

    --
    -- * Getting information about images.
    --

    -- | Get the size of an image.
    imageSize :: Image -> IO (Int,Int) -- ^ (width, height)
    imageSize :: Image -> IO Size
    imageSize Image
    i = ((Color, Color) -> Size) -> IO (Color, Color) -> IO Size
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM (Color, Color) -> Size
    f (IO (Color, Color) -> IO Size) -> IO (Color, Color) -> IO Size
    forall a b. (a -> b) -> a -> b
    $ Image -> (Ptr GDImage -> IO (Color, Color)) -> IO (Color, Color)
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i Ptr GDImage -> IO (Color, Color)
    imageSize_
        where f :: (Color, Color) -> Size
    f = (\ (Color
    w,Color
    h) -> (Color -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Color
    w, Color -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Color
    h))

    imageSize_ :: Ptr GDImage -> IO (CInt,CInt)
    imageSize_ :: Ptr GDImage -> IO (Color, Color)
    imageSize_ Ptr GDImage
    p = do w <- (\Ptr GDImage
    hsc_ptr -> Ptr GDImage -> Int -> IO Color
    forall b. Ptr b -> Int -> IO Color
    forall a b. Storable a => Ptr b -> Int -> IO a
    peekByteOff Ptr GDImage
    hsc_ptr Int
    8) Ptr GDImage
    p
    {-# LINE 455 "Graphics/GD.hsc" #-}
                      h <- (\Ptr GDImage
    hsc_ptr -> Ptr GDImage -> Int -> IO Color
    forall b. Ptr b -> Int -> IO Color
    forall a b. Storable a => Ptr b -> Int -> IO a
    peekByteOff Ptr GDImage
    hsc_ptr Int
    12) p
    {-# LINE 456 "Graphics/GD.hsc" #-}
                      return (w, h)

    --
    -- * Transforming images.
    --

    -- | Resize an image to a give size.
    resizeImage :: Int -- ^ width in pixels of output image
                -> Int -- ^ height in pixels of output image
                -> Image
                -> IO Image
    resizeImage :: Int -> Int -> Image -> IO Image
    resizeImage Int
    w Int
    h Image
    i = Image -> (Ptr GDImage -> IO Image) -> IO Image
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i Ptr GDImage -> IO Image
    f
        where
          f :: Ptr GDImage -> IO Image
    f Ptr GDImage
    p = do let (Color
    outW,Color
    outH) = (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    w, Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    h)
                   (inW, inH) <- Ptr GDImage -> IO (Color, Color)
    imageSize_ Ptr GDImage
    p
                   onNewImage outW outH $ \Ptr GDImage
    p' ->
                       Ptr GDImage
    -> Ptr GDImage
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> IO ()
    gdImageCopyResampled Ptr GDImage
    p' Ptr GDImage
    p Color
    0 Color
    0 Color
    0 Color
    0 Color
    outW Color
    outH Color
    inW Color
    inH

    -- | Rotate an image by a multiple of 90 degrees counter-clockwise.
    rotateImage :: Int -- ^ 1 for 90 degrees counter-clockwise,
                       -- 2 for 180 degrees, etc.
                -> Image
                -> IO Image
    rotateImage :: Int -> Image -> IO Image
    rotateImage Int
    r Image
    i = Image -> (Ptr GDImage -> IO Image) -> IO Image
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i Ptr GDImage -> IO Image
    f
        where f :: Ptr GDImage -> IO Image
    f Ptr GDImage
    p = do (inW,inH) <- Ptr GDImage -> IO (Color, Color)
    imageSize_ Ptr GDImage
    p
                       let q = Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int
    r Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4)
                           (outW,outH) | r `mod` 2 == 0 = (inW,inH)
                                       | otherwise      = (inH,inW)
                           srcX = if Color
    q Color -> Color -> Bool
    forall a. Eq a => a -> a -> Bool
    == Color
    1 Bool -> Bool -> Bool
    || Color
    q Color -> Color -> Bool
    forall a. Eq a => a -> a -> Bool
    == Color
    2 then Color
    inWColor -> Color -> Color
    forall a. Num a => a -> a -> a
    -Color
    1 else Color
    0;
                           srcY = if Color
    q Color -> Color -> Bool
    forall a. Eq a => a -> a -> Bool
    == Color
    2 Bool -> Bool -> Bool
    || Color
    q Color -> Color -> Bool
    forall a. Eq a => a -> a -> Bool
    == Color
    3 then Color
    inHColor -> Color -> Color
    forall a. Num a => a -> a -> a
    -Color
    1 else Color
    0;
                       onNewImage outW outH (\Ptr GDImage
    p' ->
                           Ptr GDImage
    -> Ptr GDImage
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> IO ()
    gdImageCopyRotated90 Ptr GDImage
    p' Ptr GDImage
    p Color
    0 Color
    0 Color
    srcX Color
    srcY Color
    inW Color
    inH Color
    q)

    --
    -- * Drawing
    --

    -- | Special character for gdBrushed
    brushed :: PCREOption
    brushed :: PCREOption
    brushed = Color -> PCREOption
    PCREOption (-Color
    3)
    {-# LINE 496 "Graphics/GD.hsc" #-}

    -- | Set an @Image@ as a brush for an @Image@
    setBrush :: Image -- ^ Source image
             -> Image -- ^ Brush
             -> IO ()
    setBrush :: Image -> Image -> IO ()
    setBrush Image
    i Image
    b =
        Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    b ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $
        \Ptr GDImage
    brushImg -> Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $
        \Ptr GDImage
    srcImg -> Ptr GDImage -> Ptr GDImage -> IO ()
    gdImageSetBrush Ptr GDImage
    srcImg Ptr GDImage
    brushImg

    -- | Fill the entire image with the given color.
    fillImage :: Color -> Image -> IO ()
    fillImage :: Color -> Image -> IO ()
    fillImage Color
    c Image
    i = do sz <- Image -> IO Size
    imageSize Image
    i
                       drawFilledRectangle (0,0) sz c i

    drawFilledRectangle :: Point -- ^ Upper left corner
                        -> Point -- ^ Lower right corner
                        -> Color -> Image -> IO ()
    drawFilledRectangle :: Size -> Size -> Color -> Image -> IO ()
    drawFilledRectangle (Int
    x1,Int
    y1) (Int
    x2,Int
    y2) Color
    c Image
    i =
        Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr GDImage
    p ->
            Ptr GDImage -> Color -> Color -> Color -> Color -> Color -> IO ()
    gdImageFilledRectangle Ptr GDImage
    p (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    x1) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    y1) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    x2) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    y2) Color
    c

    drawFilledEllipse :: Point -- ^ Center
                      -> Size  -- ^ Width and height
                      -> Color -> Image -> IO ()
    drawFilledEllipse :: Size -> Size -> Color -> Image -> IO ()
    drawFilledEllipse (Int
    cx,Int
    cy) (Int
    w,Int
    h) Color
    c Image
    i =
        Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr GDImage
    p ->
            Ptr GDImage -> Color -> Color -> Color -> Color -> Color -> IO ()
    gdImageFilledEllipse Ptr GDImage
    p (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    cx) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    cy) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    w) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    h) Color
    c

    drawLine :: Point -- ^ Start
             -> Point -- ^ End
             -> Color -> Image -> IO ()
    drawLine :: Size -> Size -> Color -> Image -> IO ()
    drawLine (Int
    x1,Int
    y1) (Int
    x2,Int
    y2) Color
    c Image
    i =
        Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr GDImage
    p ->
            Ptr GDImage -> Color -> Color -> Color -> Color -> Color -> IO ()
    gdImageLine Ptr GDImage
    p (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    x1) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    y1) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    x2) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    y2) Color
    c

    drawArc :: Point -- ^ Center
            -> Size  -- ^ Width and height
            -> Int   -- ^ Starting position (degrees)
            -> Int   -- ^ Ending position (degrees)
            -> Color -> Image -> IO ()
    drawArc :: Size -> Size -> Int -> Int -> Color -> Image -> IO ()
    drawArc (Int
    cx,Int
    cy) (Int
    w,Int
    h) Int
    sp Int
    ep Color
    c Image
    i =
        Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr GDImage
    p ->
            Ptr GDImage
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> Color
    -> IO ()
    gdImageArc Ptr GDImage
    p (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    cx) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    cy) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    w) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    h) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    sp) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    ep) Color
    c

    -- | Use anti-aliasing when performing the given drawing function.
    --   This can cause a segault with some gd versions.
    antiAliased :: (Color -> Image -> IO a) -> Color -> Image -> IO a
    antiAliased :: forall a. (Color -> Image -> IO a) -> Color -> Image -> IO a
    antiAliased Color -> Image -> IO a
    f Color
    c Image
    i =
        do Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i (\Ptr GDImage
    p -> Ptr GDImage -> Color -> IO ()
    gdImageSetAntiAliased Ptr GDImage
    p Color
    c)
           Color -> Image -> IO a
    f (-Color
    7) Image
    i
    {-# LINE 547 "Graphics/GD.hsc" #-}

    setPixel :: Point -> Color -> Image -> IO ()
    setPixel :: Size -> Color -> Image -> IO ()
    setPixel (Int
    x,Int
    y) Color
    c Image
    i =
        Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr GDImage
    p ->
            Ptr GDImage -> Color -> Color -> Color -> IO ()
    gdImageSetPixel Ptr GDImage
    p (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    x) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    y) Color
    c

    colorAllocate :: CInt -> CInt -> CInt -> CInt -> Image -> IO Color
    colorAllocate :: Color -> Color -> Color -> Color -> Image -> IO Color
    colorAllocate Color
    r Color
    g Color
    b Color
    a Image
    i =
        Image -> (Ptr GDImage -> IO Color) -> IO Color
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i ((Ptr GDImage -> IO Color) -> IO Color)
    -> (Ptr GDImage -> IO Color) -> IO Color
    forall a b. (a -> b) -> a -> b
    $ \Ptr GDImage
    p ->
            Ptr GDImage -> Color -> Color -> Color -> Color -> IO Color
    gdImageColorAllocate Ptr GDImage
    p Color
    r Color
    g Color
    b Color
    a

    --
    -- * Text
    --

    -- | Globally switch from using font file names to fontconfig paths
    -- | for fonts in drawString (and measureString).
    useFontConfig :: Bool -> IO Bool
    useFontConfig :: Bool -> IO Bool
    useFontConfig Bool
    use = (Color -> Bool) -> IO Color -> IO Bool
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM (Color -> Color -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Color
    0) (IO Color -> IO Bool) -> IO Color -> IO Bool
    forall a b. (a -> b) -> a -> b
    $ Color -> IO Color
    gdFTUseFontConfig (Color -> IO Color) -> Color -> IO Color
    forall a b. (a -> b) -> a -> b
    $ if Bool
    use then Color
    1 else Color
    0

    -- | Draw a string using the FreeType 2.x library
    drawString :: String -- ^ Font name
               -> Double -- ^ Font point size
               -> Double -- ^ Angle in counterclockwise radians
               -> Point -- ^ Origin
               -> String -- ^ Text, including HTML entities
               -> Color -> Image
               -> IO (Point, Point, Point, Point) -- ^ Bounding box
                                                  -- of the drawn
                                                  -- text.
    drawString :: FilePath
    -> Double
    -> Double
    -> Size
    -> FilePath
    -> Color
    -> Image
    -> IO (Size, Size, Size, Size)
    drawString FilePath
    fontName Double
    ptSize Double
    angle (Int
    oriX, Int
    oriY) FilePath
    txt Color
    color Image
    img
        = Image
    -> (Ptr GDImage -> IO (Size, Size, Size, Size))
    -> IO (Size, Size, Size, Size)
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    img ((Ptr GDImage -> IO (Size, Size, Size, Size))
     -> IO (Size, Size, Size, Size))
    -> (Ptr GDImage -> IO (Size, Size, Size, Size))
    -> IO (Size, Size, Size, Size)
    forall a b. (a -> b) -> a -> b
    $
            Color
    -> FilePath
    -> Double
    -> Double
    -> Size
    -> FilePath
    -> Ptr GDImage
    -> IO (Size, Size, Size, Size)
    drawStringImagePtr Color
    color FilePath
    fontName Double
    ptSize Double
    angle (Int
    oriX, Int
    oriY) FilePath
    txt

    -- | Measure a string using the FreeType 2.x library.  This computes
    -- the bounding box but does not actually draw the string to any
    -- image.
    measureString :: String -- ^ Font name
                  -> Double -- ^ Font point size
                  -> Double -- ^ Angle in counterclockwise radians
                  -> Point -- ^ Origin
                  -> String -- ^ Text, including HTML entities
                  -> Color
                  -> IO (Point, Point, Point, Point) -- ^ Bounding
                                                     -- box of the
                                                     -- drawn text
    measureString :: FilePath
    -> Double
    -> Double
    -> Size
    -> FilePath
    -> Color
    -> IO (Size, Size, Size, Size)
    measureString FilePath
    fontName Double
    ptSize Double
    angle (Int
    oriX, Int
    oriY) FilePath
    txt Color
    color
        = Color
    -> FilePath
    -> Double
    -> Double
    -> Size
    -> FilePath
    -> Ptr GDImage
    -> IO (Size, Size, Size, Size)
    drawStringImagePtr Color
    color FilePath
    fontName Double
    ptSize Double
    angle (Int
    oriX, Int
    oriY) FilePath
    txt Ptr GDImage
    forall a. Ptr a
    F.nullPtr

    drawStringImagePtr :: Color -> String -> Double -> Double -> Point -> String ->
                          Ptr GDImage -> IO (Point, Point, Point, Point)
    drawStringImagePtr :: Color
    -> FilePath
    -> Double
    -> Double
    -> Size
    -> FilePath
    -> Ptr GDImage
    -> IO (Size, Size, Size, Size)
    drawStringImagePtr Color
    color FilePath
    fontName Double
    ptSize Double
    angle (Int
    oriX, Int
    oriY) FilePath
    txt Ptr GDImage
    imgPtr
        = Int
    -> (Ptr Color -> IO (Size, Size, Size, Size))
    -> IO (Size, Size, Size, Size)
    forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
    F.allocaArray Int
    8 ((Ptr Color -> IO (Size, Size, Size, Size))
     -> IO (Size, Size, Size, Size))
    -> (Ptr Color -> IO (Size, Size, Size, Size))
    -> IO (Size, Size, Size, Size)
    forall a b. (a -> b) -> a -> b
    $
          \Ptr Color
    bboxPtr -> FilePath
    -> (CString -> IO (Size, Size, Size, Size))
    -> IO (Size, Size, Size, Size)
    forall a. FilePath -> (CString -> IO a) -> IO a
    C.withCAString FilePath
    fontName ((CString -> IO (Size, Size, Size, Size))
     -> IO (Size, Size, Size, Size))
    -> (CString -> IO (Size, Size, Size, Size))
    -> IO (Size, Size, Size, Size)
    forall a b. (a -> b) -> a -> b
    $
          \CString
    cFontName -> FilePath
    -> (CString -> IO (Size, Size, Size, Size))
    -> IO (Size, Size, Size, Size)
    forall a. FilePath -> (CString -> IO a) -> IO a
    C.withCAString FilePath
    txt ((CString -> IO (Size, Size, Size, Size))
     -> IO (Size, Size, Size, Size))
    -> (CString -> IO (Size, Size, Size, Size))
    -> IO (Size, Size, Size, Size)
    forall a b. (a -> b) -> a -> b
    $
          \CString
    cTxt -> do res <- Ptr GDImage
    -> Ptr Color
    -> Color
    -> CString
    -> CDouble
    -> CDouble
    -> Color
    -> Color
    -> CString
    -> IO CString
    gdImageStringFT Ptr GDImage
    imgPtr Ptr Color
    bboxPtr Color
    color CString
    cFontName
                                             (Double -> CDouble
    forall a b. (Real a, Fractional b) => a -> b
    double Double
    ptSize) (Double -> CDouble
    forall a b. (Real a, Fractional b) => a -> b
    double Double
    angle)
                                             (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    oriX) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    oriY) CString
    cTxt
                      if res == F.nullPtr
                         then F.peekArray 8 bboxPtr >>= parseBBox
                         else C.peekCAString res >>= ioError . userError
        where parseBBox :: [a] -> IO ((b, b), (b, b), (b, b), (b, b))
    parseBBox [a]
    l =
                case (a -> b) -> [a] -> [b]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> b
    forall a b. (Integral a, Num b) => a -> b
    int [a]
    l of
                  [b
    llx, b
    lly, b
    lrx, b
    lry, b
    urx, b
    ury, b
    ulx, b
    uly] ->
                    ((b, b), (b, b), (b, b), (b, b))
    -> IO ((b, b), (b, b), (b, b), (b, b))
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((b
    llx, b
    lly), (b
    lrx, b
    lry), (b
    urx, b
    ury), (b
    ulx, b
    uly))
                  [b]
    _ -> IOError -> IO ((b, b), (b, b), (b, b), (b, b))
    forall a. IOError -> IO a
    ioError (IOError -> IO ((b, b), (b, b), (b, b), (b, b)))
    -> IOError -> IO ((b, b), (b, b), (b, b), (b, b))
    forall a b. (a -> b) -> a -> b
    $ FilePath -> IOError
    userError (FilePath -> IOError) -> FilePath -> IOError
    forall a b. (a -> b) -> a -> b
    $
                         FilePath
    "parseBBox with /= 8 elements: " FilePath -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [a] -> FilePath
    forall a. Show a => a -> FilePath
    show [a]
    l

    -- | Draw strings around the top and bottom of a torus
    drawStringCircle :: Point -- ^ Center of text path circle
                     -> Double -- ^ Outer radius of text
                     -> Double -- ^ Fraction of radius occupied by text
                     -> Double -- ^ Portion of circle arc filled by text
                     -> String -- ^ Font name
                     -> Double -- ^ Font size hint
                     -> String -- ^ Text to write on the top of the circle
                     -> String -- ^ Text to write on the bottom of the circle
                     -> Color -- ^ Text color
                     -> Image -> IO ()
    drawStringCircle :: Size
    -> Double
    -> Double
    -> Double
    -> FilePath
    -> Double
    -> FilePath
    -> FilePath
    -> Color
    -> Image
    -> IO ()
    drawStringCircle (Int
    ctrX, Int
    ctrY) Double
    rad Double
    textRad Double
    textFill FilePath
    fontName
                     Double
    fontSize FilePath
    topTxt FilePath
    bottomTxt Color
    color Image
    img
        = FilePath -> (CString -> IO ()) -> IO ()
    forall a. FilePath -> (CString -> IO a) -> IO a
    C.withCAString FilePath
    fontName ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          \CString
    cFontName -> FilePath -> (CString -> IO ()) -> IO ()
    forall a. FilePath -> (CString -> IO a) -> IO a
    C.withCAString FilePath
    topTxt ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          \CString
    cTopTxt -> FilePath -> (CString -> IO ()) -> IO ()
    forall a. FilePath -> (CString -> IO a) -> IO a
    C.withCAString FilePath
    bottomTxt ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          \CString
    cBottomTxt -> Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    img ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $
          \Ptr GDImage
    imgPtr -> do
            res <- Ptr GDImage
    -> Color
    -> Color
    -> CDouble
    -> CDouble
    -> CDouble
    -> CString
    -> CDouble
    -> CString
    -> CString
    -> Color
    -> IO CString
    gdImageStringFTCircle Ptr GDImage
    imgPtr
                       (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    ctrX) (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    ctrY) (Double -> CDouble
    forall a b. (Real a, Fractional b) => a -> b
    double Double
    rad) (Double -> CDouble
    forall a b. (Real a, Fractional b) => a -> b
    double Double
    textRad)
                       (Double -> CDouble
    forall a b. (Real a, Fractional b) => a -> b
    double Double
    textFill) CString
    cFontName (Double -> CDouble
    forall a b. (Real a, Fractional b) => a -> b
    double Double
    fontSize)
                       CString
    cTopTxt CString
    cBottomTxt  Color
    color
            unless (res == F.nullPtr) (C.peekCAString res >>= ioError . userError)

    saveAlpha :: Bool -> Image -> IO ()
    saveAlpha :: Bool -> Image -> IO ()
    saveAlpha Bool
    b Image
    i = Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr GDImage
    p -> Ptr GDImage -> Color -> IO ()
    gdImageSaveAlpha Ptr GDImage
    p (Color -> IO ()) -> Color -> IO ()
    forall a b. (a -> b) -> a -> b
    $ if Bool
    b then Color
    1 else Color
    0

    alphaBlending :: Bool -> Image -> IO ()
    alphaBlending :: Bool -> Image -> IO ()
    alphaBlending Bool
    b Image
    i = Image -> (Ptr GDImage -> IO ()) -> IO ()
    forall a. Image -> (Ptr GDImage -> IO a) -> IO a
    withImagePtr Image
    i ((Ptr GDImage -> IO ()) -> IO ())
    -> (Ptr GDImage -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr GDImage
    p -> Ptr GDImage -> Color -> IO ()
    gdImageAlphaBlending Ptr GDImage
    p (Color -> IO ()) -> Color -> IO ()
    forall a b. (a -> b) -> a -> b
    $ if Bool
    b then Color
    1 else Color
    0

    --
    -- * Colors
    --

    rgb :: Int -- ^ Red (0-255)
             -> Int -- ^ Green (0-255)
             -> Int -- ^ Blue (0-255)
             -> Color
    rgb :: Int -> Int -> Int -> Color
    rgb Int
    r Int
    g Int
    b = Int -> Int -> Int -> Int -> Color
    rgba Int
    r Int
    g Int
    b Int
    0

    rgba :: Int -- ^ Red (0-255)
              -> Int -- ^ Green (0-255)
              -> Int -- ^ Blue (0-255)
              -> Int -- ^ Alpha (0-127), 0 is opaque, 127 is transparent
              -> Color
    rgba :: Int -> Int -> Int -> Int -> Color
    rgba Int
    r Int
    g Int
    b Int
    a =
        (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    a Color -> Int -> Color
    forall a. Bits a => a -> Int -> a
    `F.shiftL` Int
    24) Color -> Color -> Color
    forall a. Bits a => a -> a -> a
    .|.
        (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    r Color -> Int -> Color
    forall a. Bits a => a -> Int -> a
    `F.shiftL` Int
    16) Color -> Color -> Color
    forall a. Bits a => a -> a -> a
    .|.
        (Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    g Color -> Int -> Color
    forall a. Bits a => a -> Int -> a
    `F.shiftL` Int
    8)  Color -> Color -> Color
    forall a. Bits a => a -> a -> a
    .|.
        Int -> Color
    forall a b. (Integral a, Num b) => a -> b
    int Int
    b

    --
    -- * Utilities
    --

    int :: (Integral a, Num b) => a -> b
    int :: forall a b. (Integral a, Num b) => a -> b
    int = a -> b
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral

    double :: (Real a, Fractional b) => a -> b
    double :: forall a b. (Real a, Fractional b) => a -> b
    double = a -> b
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac