{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Graphics.Image.IO.Formats.JuicyPixels
(
SaveOption(..)
, BMP(..)
, GIF(..)
, GIFA(..)
, JP.GifDelay
, JP.GifLooping(..)
, JP.PaletteOptions(..)
, JP.PaletteCreationMethod(..)
, HDR(..)
, JPG(..)
, PNG(..)
, TGA(..)
, TIF(..)
, toJPImageY8
, toJPImageYA8
, toJPImageY16
, toJPImageYA16
, toJPImageYF
, toJPImageRGB8
, toJPImageRGBA8
, toJPImageRGB16
, toJPImageRGBA16
, toJPImageRGBF
, toJPImageYCbCr8
, toJPImageCMYK8
, toJPImageCMYK16
, fromJPImageY8
, fromJPImageYA8
, fromJPImageY16
, fromJPImageYA16
, fromJPImageYF
, fromJPImageRGB8
, fromJPImageRGBA8
, fromJPImageRGB16
, fromJPImageRGBA16
, fromJPImageRGBF
, fromJPImageYCbCr8
, fromJPImageCMYK8
, fromJPImageCMYK16
) where
import Prelude as P
import qualified Codec.Picture as JP
import qualified Codec.Picture.ColorQuant as JP
import qualified Codec.Picture.Gif as JP
import qualified Codec.Picture.Jpg as JP
import Control.Monad ((<=<))
import qualified Data.ByteString as B (ByteString)
import qualified Data.ByteString.Lazy as BL (ByteString)
import qualified Data.Monoid as M (mempty)
import qualified Data.Vector.Storable as V
import Graphics.Image.ColorSpace
import Graphics.Image.Interface as I
import Graphics.Image.Interface.Vector (VS)
import Graphics.Image.IO.Base
imageToJPImageUnsafe
:: (JP.Pixel a, Array VS cs (JP.PixelBaseComponent a))
=> Image VS cs (JP.PixelBaseComponent a)
-> JP.Image a
imageToJPImageUnsafe img = JP.Image n m $ V.unsafeCast $ toVector img where
(m, n) = dims img
{-# INLINE imageToJPImageUnsafe #-}
toJPImageY8 :: Image VS Y Word8 -> JP.Image JP.Pixel8
toJPImageY8 = imageToJPImageUnsafe
{-# INLINE toJPImageY8 #-}
toJPImageY16 :: Image VS Y Word16 -> JP.Image JP.Pixel16
toJPImageY16 = imageToJPImageUnsafe
{-# INLINE toJPImageY16 #-}
toJPImageYA8 :: Image VS YA Word8 -> JP.Image JP.PixelYA8
toJPImageYA8 = imageToJPImageUnsafe
{-# INLINE toJPImageYA8 #-}
toJPImageYA16 :: Image VS YA Word16 -> JP.Image JP.PixelYA16
toJPImageYA16 = imageToJPImageUnsafe
{-# INLINE toJPImageYA16 #-}
toJPImageYF :: Image VS Y Float -> JP.Image JP.PixelF
toJPImageYF = imageToJPImageUnsafe
{-# INLINE toJPImageYF #-}
toJPImageRGB8 :: Image VS RGB Word8 -> JP.Image JP.PixelRGB8
toJPImageRGB8 = imageToJPImageUnsafe
{-# INLINE toJPImageRGB8 #-}
toJPImageRGBA8 :: Image VS RGBA Word8 -> JP.Image JP.PixelRGBA8
toJPImageRGBA8 = imageToJPImageUnsafe
{-# INLINE toJPImageRGBA8 #-}
toJPImageRGB16 :: Image VS RGB Word16 -> JP.Image JP.PixelRGB16
toJPImageRGB16 = imageToJPImageUnsafe
{-# INLINE toJPImageRGB16 #-}
toJPImageRGBA16 :: Image VS RGBA Word16 -> JP.Image JP.PixelRGBA16
toJPImageRGBA16 = imageToJPImageUnsafe
{-# INLINE toJPImageRGBA16 #-}
toJPImageRGBF :: Image VS RGB Float -> JP.Image JP.PixelRGBF
toJPImageRGBF = imageToJPImageUnsafe
{-# INLINE toJPImageRGBF #-}
toJPImageYCbCr8 :: Image VS YCbCr Word8 -> JP.Image JP.PixelYCbCr8
toJPImageYCbCr8 = imageToJPImageUnsafe
{-# INLINE toJPImageYCbCr8 #-}
toJPImageCMYK8 :: Image VS CMYK Word8 -> JP.Image JP.PixelCMYK8
toJPImageCMYK8 = imageToJPImageUnsafe
{-# INLINE toJPImageCMYK8 #-}
toJPImageCMYK16 :: Image VS CMYK Word16 -> JP.Image JP.PixelCMYK16
toJPImageCMYK16 = imageToJPImageUnsafe
{-# INLINE toJPImageCMYK16 #-}
jpImageToImageUnsafe :: (Array VS cs e, JP.Pixel jpx) =>
JP.Image jpx -> Image VS cs e
jpImageToImageUnsafe (JP.Image n m !v) = fromVector (m, n) $ V.unsafeCast v
{-# INLINE jpImageToImageUnsafe #-}
fromJPImageY8 :: JP.Image JP.Pixel8 -> Image VS Y Word8
fromJPImageY8 = jpImageToImageUnsafe
{-# INLINE fromJPImageY8 #-}
fromJPImageY16 :: JP.Image JP.Pixel16 -> Image VS Y Word16
fromJPImageY16 = jpImageToImageUnsafe
{-# INLINE fromJPImageY16 #-}
fromJPImageYA8 :: JP.Image JP.PixelYA8 -> Image VS YA Word8
fromJPImageYA8 = jpImageToImageUnsafe
{-# INLINE fromJPImageYA8 #-}
fromJPImageYA16 :: JP.Image JP.PixelYA16 -> Image VS YA Word16
fromJPImageYA16 = jpImageToImageUnsafe
{-# INLINE fromJPImageYA16 #-}
fromJPImageRGB8 :: JP.Image JP.PixelRGB8 -> Image VS RGB Word8
fromJPImageRGB8 = jpImageToImageUnsafe
{-# INLINE fromJPImageRGB8 #-}
fromJPImageYF :: JP.Image JP.PixelF -> Image VS Y Float
fromJPImageYF = jpImageToImageUnsafe
{-# INLINE fromJPImageYF #-}
fromJPImageRGBA8 :: JP.Image JP.PixelRGBA8 -> Image VS RGBA Word8
fromJPImageRGBA8 = jpImageToImageUnsafe
{-# INLINE fromJPImageRGBA8 #-}
fromJPImageRGB16 :: JP.Image JP.PixelRGB16 -> Image VS RGB Word16
fromJPImageRGB16 = jpImageToImageUnsafe
{-# INLINE fromJPImageRGB16 #-}
fromJPImageRGBA16 :: JP.Image JP.PixelRGBA16 -> Image VS RGBA Word16
fromJPImageRGBA16 = jpImageToImageUnsafe
{-# INLINE fromJPImageRGBA16 #-}
fromJPImageRGBF :: JP.Image JP.PixelRGBF -> Image VS RGB Float
fromJPImageRGBF = jpImageToImageUnsafe
{-# INLINE fromJPImageRGBF #-}
fromJPImageYCbCr8 :: JP.Image JP.PixelYCbCr8 -> Image VS YCbCr Word8
fromJPImageYCbCr8 = jpImageToImageUnsafe
{-# INLINE fromJPImageYCbCr8 #-}
fromJPImageCMYK8 :: JP.Image JP.PixelCMYK8 -> Image VS CMYK Word8
fromJPImageCMYK8 = jpImageToImageUnsafe
{-# INLINE fromJPImageCMYK8 #-}
fromJPImageCMYK16 :: JP.Image JP.PixelCMYK16 -> Image VS CMYK Word16
fromJPImageCMYK16 = jpImageToImageUnsafe
{-# INLINE fromJPImageCMYK16 #-}
jpImageY8ToImage :: JP.DynamicImage -> Either String (Image VS Y Word8)
jpImageY8ToImage (JP.ImageY8 jimg) = Right (fromJPImageY8 jimg)
jpImageY8ToImage jimg = jpCSError "Y8 (Pixel Y Word8)" jimg
{-# INLINE jpImageY8ToImage #-}
jpImageY16ToImage :: JP.DynamicImage -> Either String (Image VS Y Word16)
jpImageY16ToImage (JP.ImageY16 jimg) = Right (fromJPImageY16 jimg)
jpImageY16ToImage jimg = jpCSError "Y16 (Pixel Y Word16)" jimg
{-# INLINE jpImageY16ToImage #-}
jpImageYA8ToImage :: JP.DynamicImage -> Either String (Image VS YA Word8)
jpImageYA8ToImage (JP.ImageYA8 jimg) = Right (fromJPImageYA8 jimg)
jpImageYA8ToImage jimg = jpCSError "YA8 (Pixel YA Word8)" jimg
{-# INLINE jpImageYA8ToImage #-}
jpImageYA16ToImage :: JP.DynamicImage -> Either String (Image VS YA Word16)
jpImageYA16ToImage (JP.ImageYA16 jimg) = Right (fromJPImageYA16 jimg)
jpImageYA16ToImage jimg = jpCSError "YA16 (Pixel YA Word16)" jimg
{-# INLINE jpImageYA16ToImage #-}
jpImageRGB8ToImage :: JP.DynamicImage -> Either String (Image VS RGB Word8)
jpImageRGB8ToImage (JP.ImageRGB8 jimg) = Right (fromJPImageRGB8 jimg)
jpImageRGB8ToImage jimg = jpCSError "RGB8 (Pixel RGB Word8)" jimg
{-# INLINE jpImageRGB8ToImage #-}
jpImageRGB16ToImage :: JP.DynamicImage -> Either String (Image VS RGB Word16)
jpImageRGB16ToImage (JP.ImageRGB16 jimg) = Right (fromJPImageRGB16 jimg)
jpImageRGB16ToImage jimg = jpCSError "RGB16 (Pixel RGB Word16)" jimg
{-# INLINE jpImageRGB16ToImage #-}
jpImageRGBFToImage :: JP.DynamicImage -> Either String (Image VS RGB Float)
jpImageRGBFToImage (JP.ImageRGBF jimg) = Right (fromJPImageRGBF jimg)
jpImageRGBFToImage jimg = jpCSError "RGBF (Pixel RGB Float)" jimg
{-# INLINE jpImageRGBFToImage #-}
jpImageRGBA8ToImage :: JP.DynamicImage -> Either String (Image VS RGBA Word8)
jpImageRGBA8ToImage (JP.ImageRGBA8 jimg) = Right (fromJPImageRGBA8 jimg)
jpImageRGBA8ToImage jimg = jpCSError "RGBA8 (Pixel RGBA Word8)" jimg
{-# INLINE jpImageRGBA8ToImage #-}
jpImageRGBA16ToImage :: JP.DynamicImage -> Either String (Image VS RGBA Word16)
jpImageRGBA16ToImage (JP.ImageRGBA16 jimg) = Right (fromJPImageRGBA16 jimg)
jpImageRGBA16ToImage jimg = jpCSError "RGBA16 (Pixel RGBA Word16)" jimg
{-# INLINE jpImageRGBA16ToImage #-}
jpImageYCbCr8ToImage :: JP.DynamicImage -> Either String (Image VS YCbCr Word8)
jpImageYCbCr8ToImage (JP.ImageYCbCr8 jimg) = Right (fromJPImageYCbCr8 jimg)
jpImageYCbCr8ToImage jimg = jpCSError "YCbCr8 (Pixel YCbCr Word8)" jimg
{-# INLINE jpImageYCbCr8ToImage #-}
jpImageCMYK8ToImage :: JP.DynamicImage -> Either String (Image VS CMYK Word8)
jpImageCMYK8ToImage (JP.ImageCMYK8 jimg) = Right (fromJPImageCMYK8 jimg)
jpImageCMYK8ToImage jimg = jpCSError "CMYK8 (Pixel CMYK Word8)" jimg
{-# INLINE jpImageCMYK8ToImage #-}
jpImageCMYK16ToImage :: JP.DynamicImage -> Either String (Image VS CMYK Word16)
jpImageCMYK16ToImage (JP.ImageCMYK16 jimg) = Right (fromJPImageCMYK16 jimg)
jpImageCMYK16ToImage jimg = jpCSError "CMYK16 (Pixel CMYK Word16)" jimg
{-# INLINE jpImageCMYK16ToImage #-}
jpDynamicImageToImage
:: (Convertible cs e, ColorSpace cs e, V.Storable (Pixel cs e)) =>
JP.DynamicImage -> Image VS cs e
jpDynamicImageToImage (JP.ImageY8 jimg) = convert $ fromJPImageY8 jimg
jpDynamicImageToImage (JP.ImageYA8 jimg) = convert $ fromJPImageYA8 jimg
jpDynamicImageToImage (JP.ImageY16 jimg) = convert $ fromJPImageY16 jimg
jpDynamicImageToImage (JP.ImageYA16 jimg) = convert $ fromJPImageYA16 jimg
jpDynamicImageToImage (JP.ImageYF jimg) = convert $ fromJPImageYF jimg
jpDynamicImageToImage (JP.ImageRGB8 jimg) = convert $ fromJPImageRGB8 jimg
jpDynamicImageToImage (JP.ImageRGBA8 jimg) = convert $ fromJPImageRGBA8 jimg
jpDynamicImageToImage (JP.ImageRGB16 jimg) = convert $ fromJPImageRGB16 jimg
jpDynamicImageToImage (JP.ImageRGBA16 jimg) = convert $ fromJPImageRGBA16 jimg
jpDynamicImageToImage (JP.ImageRGBF jimg) = convert $ fromJPImageRGBF jimg
jpDynamicImageToImage (JP.ImageYCbCr8 jimg) = convert $ fromJPImageYCbCr8 jimg
jpDynamicImageToImage (JP.ImageCMYK8 jimg) = convert $ fromJPImageCMYK8 jimg
jpDynamicImageToImage (JP.ImageCMYK16 jimg) = convert $ fromJPImageCMYK16 jimg
{-# INLINE jpDynamicImageToImage #-}
jpImageShowCS :: JP.DynamicImage -> String
jpImageShowCS (JP.ImageY8 _) = "Y8 (Pixel Y Word8)"
jpImageShowCS (JP.ImageY16 _) = "Y16 (Pixel Y Word16)"
jpImageShowCS (JP.ImageYF _) = "YF (Pixel Y Float)"
jpImageShowCS (JP.ImageYA8 _) = "YA8 (Pixel YA Word8)"
jpImageShowCS (JP.ImageYA16 _) = "YA16 (Pixel YA Word16)"
jpImageShowCS (JP.ImageRGB8 _) = "RGB8 (Pixel RGB Word8)"
jpImageShowCS (JP.ImageRGB16 _) = "RGB16 (Pixel RGB Word16)"
jpImageShowCS (JP.ImageRGBF _) = "RGBF (Pixel RGB Float)"
jpImageShowCS (JP.ImageRGBA8 _) = "RGBA8 (Pixel RGBA Word8)"
jpImageShowCS (JP.ImageRGBA16 _) = "RGBA16 (Pixel RGBA Word16)"
jpImageShowCS (JP.ImageYCbCr8 _) = "YCbCr8 (Pixel YCbCr Word8)"
jpImageShowCS (JP.ImageCMYK8 _) = "CMYK8 (Pixel CMYK Word8)"
jpImageShowCS (JP.ImageCMYK16 _) = "CMYK16 (Pixel CMYK Word16)"
jpError :: String -> Either String a
jpError err = Left $ "JuicyPixel decoding error: " ++ err
jpCSError :: String -> JP.DynamicImage -> Either String a
jpCSError cs jimg =
jpError $
"Input image is in " ++
jpImageShowCS jimg ++ ", cannot convert it to " ++ cs ++ " colorspace."
data BMP = BMP deriving Show
instance ImageFormat BMP where
data SaveOption BMP
ext _ = ".bmp"
instance Readable (Image VS X Bit) BMP where
decode _ = fmap toImageBinary . jpImageY8ToImage <=< JP.decodeBitmap
instance Readable (Image VS Y Word8) BMP where
decode _ = jpImageY8ToImage <=< JP.decodeBitmap
instance Readable (Image VS RGB Word8) BMP where
decode _ = jpImageRGB8ToImage <=< JP.decodeBitmap
instance Readable (Image VS RGBA Word8) BMP where
decode _ = jpImageRGBA8ToImage <=< JP.decodeBitmap
instance Readable (Image VS Y Double) BMP where
decode _ = fmap jpDynamicImageToImage . JP.decodeBitmap
instance Readable (Image VS YA Double) BMP where
decode _ = fmap jpDynamicImageToImage . JP.decodeBitmap
instance Readable (Image VS RGB Double) BMP where
decode _ = fmap jpDynamicImageToImage . JP.decodeBitmap
instance Readable (Image VS RGBA Double) BMP where
decode _ = fmap jpDynamicImageToImage . JP.decodeBitmap
instance Writable (Image VS Y Word8) BMP where
encode _ _ = JP.encodeBitmap . toJPImageY8
instance Writable (Image VS RGB Word8) BMP where
encode _ _ = JP.encodeBitmap . toJPImageRGB8
instance Writable (Image VS RGBA Word8) BMP where
encode _ _ = JP.encodeBitmap . toJPImageRGBA8
instance Writable (Image VS X Bit) BMP where
encode _ _ = JP.encodeBitmap . toJPImageY8 . fromImageBinary
instance Writable (Image VS Y Double) BMP where
encode _ _ = JP.encodeBitmap . toJPImageY8 . toWord8I
instance Writable (Image VS YA Double) BMP where
encode _ _ = JP.encodeBitmap . toJPImageY8 . toWord8I . toImageY
instance Writable (Image VS RGB Double) BMP where
encode _ _ = JP.encodeBitmap . toJPImageRGB8 . toWord8I
instance Writable (Image VS RGBA Double) BMP where
encode _ _ = JP.encodeBitmap . toJPImageRGBA8 . toWord8I
data GIF = GIF deriving Show
instance ImageFormat GIF where
data SaveOption GIF = GIFPalette JP.PaletteOptions
ext _ = ".gif"
data GIFA = GIFA deriving Show
{-# DEPRECATED GIFA "use (`Seq` `GIF`) instead" #-}
instance ImageFormat GIFA where
data SaveOption GIFA = GIFAPalette JP.PaletteOptions
| GIFALooping JP.GifLooping
ext _ = ext GIF
instance ImageFormat (Seq GIF) where
data SaveOption (Seq GIF) = GIFSeqPalette JP.PaletteOptions
| GIFSeqLooping JP.GifLooping
ext _ = ext GIF
instance Readable (Image VS RGB Word8) GIF where
decode _ = jpImageRGB8ToImage <=< JP.decodeGif
instance Readable (Image VS RGBA Word8) GIF where
decode _ = jpImageRGBA8ToImage <=< JP.decodeGif
instance Readable (Image VS Y Double) GIF where
decode _ = fmap jpDynamicImageToImage . JP.decodeGif
instance Readable (Image VS YA Double) GIF where
decode _ = fmap jpDynamicImageToImage . JP.decodeGif
instance Readable (Image VS RGB Double) GIF where
decode _ = fmap jpDynamicImageToImage . JP.decodeGif
instance Readable (Image VS RGBA Double) GIF where
decode _ = fmap jpDynamicImageToImage . JP.decodeGif
decodeGifs :: (JP.DynamicImage -> Either String img)
-> B.ByteString -> Either String [img]
decodeGifs decoder bs = do
imgs <- JP.decodeGifImages bs
sequence $ fmap decoder imgs
decodeGifsDelays :: (JP.DynamicImage -> Either String img)
-> B.ByteString -> Either String [(JP.GifDelay, img)]
decodeGifsDelays decoder bs = do
imgs <- JP.decodeGifImages bs
delays <- JP.getDelaysGifImages bs
gifs <- sequence $ fmap decoder imgs
return $ zip delays gifs
instance Readable [Image VS RGB Word8] GIFA where
decode _ = decodeGifs jpImageRGB8ToImage
instance Readable [Image VS RGBA Word8] GIFA where
decode _ = decodeGifs jpImageRGBA8ToImage
instance Readable [(JP.GifDelay, Image VS RGB Word8)] GIFA where
decode _ = decodeGifsDelays jpImageRGB8ToImage
instance Readable [(JP.GifDelay, Image VS RGBA Word8)] GIFA where
decode _ = decodeGifsDelays jpImageRGBA8ToImage
instance Readable [Image VS Y Double] GIFA where
decode _ = decodeGifs (Right . jpDynamicImageToImage)
instance Readable [Image VS YA Double] GIFA where
decode _ = decodeGifs (Right . jpDynamicImageToImage)
instance Readable [Image VS RGB Double] GIFA where
decode _ = decodeGifs (Right . jpDynamicImageToImage)
instance Readable [Image VS RGBA Double] GIFA where
decode _ = decodeGifs (Right . jpDynamicImageToImage)
instance Readable [Image VS RGB Word8] (Seq GIF) where
decode _ = decodeGifs jpImageRGB8ToImage
instance Readable [Image VS RGBA Word8] (Seq GIF) where
decode _ = decodeGifs jpImageRGBA8ToImage
instance Readable [(JP.GifDelay, Image VS RGB Word8)] (Seq GIF) where
decode _ = decodeGifsDelays jpImageRGB8ToImage
instance Readable [(JP.GifDelay, Image VS RGBA Word8)] (Seq GIF) where
decode _ = decodeGifsDelays jpImageRGBA8ToImage
instance Readable [Image VS Y Double] (Seq GIF) where
decode _ = decodeGifs (Right . jpDynamicImageToImage)
instance Readable [Image VS YA Double] (Seq GIF) where
decode _ = decodeGifs (Right . jpDynamicImageToImage)
instance Readable [Image VS RGB Double] (Seq GIF) where
decode _ = decodeGifs (Right . jpDynamicImageToImage)
instance Readable [Image VS RGBA Double] (Seq GIF) where
decode _ = decodeGifs (Right . jpDynamicImageToImage)
encodeGIF :: [SaveOption GIF]
-> Image VS RGB Word8
-> BL.ByteString
encodeGIF [] =
either error id . uncurry JP.encodeGifImageWithPalette .
JP.palettize JP.defaultPaletteOptions . toJPImageRGB8
encodeGIF (GIFPalette palOpts:_) =
either error id . uncurry JP.encodeGifImageWithPalette .
JP.palettize palOpts . toJPImageRGB8
{-# INLINE encodeGIF #-}
instance Writable (Image VS RGB Word8) GIF where
encode _ = encodeGIF
instance Writable (Image VS Y Double) GIF where
encode _ _ = JP.encodeGifImage . toJPImageY8 . toWord8I
instance Writable (Image VS YA Double) GIF where
encode f opts = encode f opts . toImageY
instance Writable (Image VS RGB Double) GIF where
encode _ opts = encodeGIF opts . toWord8I
instance Writable (Image VS RGBA Double) GIF where
encode f opts = encode f opts . toImageRGB
encodeGIFA :: [SaveOption GIFA]
-> [(JP.GifDelay, Image VS RGB Word8)] -> BL.ByteString
encodeGIFA !opts =
either error id . JP.encodeGifImages (getGIFALoop opts) . P.map palletizeGif where
getGIFALoop [] = JP.LoopingNever
getGIFALoop (GIFALooping l:_) = l
getGIFALoop (_:xs) = getGIFALoop xs
getGIFAPal [] = JP.defaultPaletteOptions
getGIFAPal (GIFAPalette palOpts:_) = palOpts
getGIFAPal (_:xs) = getGIFAPal xs
palletizeGif !(d, img) = (p, d, jimg) where
!(jimg, p) = JP.palettize (getGIFAPal opts) $ toJPImageRGB8 img
instance Writable [(JP.GifDelay, Image VS RGB Word8)] GIFA where
encode _ opts = encodeGIFA opts
instance Writable [(JP.GifDelay, Image VS RGB Double)] GIFA where
encode _ opts = encodeGIFA opts . fmap (\ !(d, i) -> (d, toWord8I i))
encodeGIFSeq :: [SaveOption (Seq GIF)]
-> [(JP.GifDelay, Image VS RGB Word8)] -> BL.ByteString
encodeGIFSeq !opts =
either error id . JP.encodeGifImages (getGIFSeqLoop opts) . P.map palletizeGif where
getGIFSeqLoop [] = JP.LoopingNever
getGIFSeqLoop (GIFSeqLooping l:_) = l
getGIFSeqLoop (_:xs) = getGIFSeqLoop xs
getGIFSeqPal [] = JP.defaultPaletteOptions
getGIFSeqPal (GIFSeqPalette palOpts:_) = palOpts
getGIFSeqPal (_:xs) = getGIFSeqPal xs
palletizeGif !(d, img) = (p, d, jimg) where
!(jimg, p) = JP.palettize (getGIFSeqPal opts) $ toJPImageRGB8 img
{-# INLINE palletizeGif #-}
{-# INLINE encodeGIFSeq #-}
instance Writable [(JP.GifDelay, Image VS RGB Word8)] (Seq GIF) where
encode _ opts = encodeGIFSeq opts
instance Writable [(JP.GifDelay, Image VS RGB Double)] (Seq GIF) where
encode _ opts = encodeGIFSeq opts . fmap (fmap toWord8I)
data HDR = HDR deriving Show
instance ImageFormat HDR where
data SaveOption HDR
ext _ = ".hdr"
exts _ = [".hdr", ".pic"]
instance Readable (Image VS RGB Float) HDR where
decode _ = jpImageRGBFToImage <=< JP.decodeHDR
instance Readable (Image VS Y Double) HDR where
decode _ = fmap jpDynamicImageToImage . JP.decodeHDR
instance Readable (Image VS YA Double) HDR where
decode _ = fmap jpDynamicImageToImage . JP.decodeHDR
instance Readable (Image VS RGB Double) HDR where
decode _ = fmap jpDynamicImageToImage . JP.decodeHDR
instance Readable (Image VS RGBA Double) HDR where
decode _ = fmap jpDynamicImageToImage . JP.decodeHDR
instance Writable (Image VS RGB Float) HDR where
encode _ _ = JP.encodeHDR . toJPImageRGBF
instance Writable (Image VS Y Double) HDR where
encode _ _ = JP.encodeHDR . toJPImageRGBF . toFloatI . toImageRGB
instance Writable (Image VS YA Double) HDR where
encode _ _ = JP.encodeHDR . toJPImageRGBF . toFloatI . toImageRGB
instance Writable (Image VS RGB Double) HDR where
encode _ _ = JP.encodeHDR . toJPImageRGBF . toFloatI
instance Writable (Image VS RGBA Double) HDR where
encode _ _ = JP.encodeHDR . toJPImageRGBF . toFloatI . toImageRGB
data JPG = JPG deriving Show
instance ImageFormat JPG where
data SaveOption JPG = JPGQuality Word8
ext _ = ".jpg"
exts _ = [".jpg", ".jpeg"]
instance Readable (Image VS Y Word8) JPG where
decode _ = jpImageY8ToImage <=< JP.decodeJpeg
instance Readable (Image VS YA Word8) JPG where
decode _ = jpImageYA8ToImage <=< JP.decodeJpeg
instance Readable (Image VS RGB Word8) JPG where
decode _ = jpImageRGB8ToImage <=< JP.decodeJpeg
instance Readable (Image VS CMYK Word8) JPG where
decode _ = jpImageCMYK8ToImage <=< JP.decodeJpeg
instance Readable (Image VS YCbCr Word8) JPG where
decode _ = jpImageYCbCr8ToImage <=< JP.decodeJpeg
instance Readable (Image VS Y Double) JPG where
decode _ = fmap jpDynamicImageToImage . JP.decodeJpeg
instance Readable (Image VS YA Double) JPG where
decode _ = fmap jpDynamicImageToImage . JP.decodeJpeg
instance Readable (Image VS RGB Double) JPG where
decode _ = fmap jpDynamicImageToImage . JP.decodeJpeg
instance Readable (Image VS RGBA Double) JPG where
decode _ = fmap jpDynamicImageToImage . JP.decodeJpeg
encodeJPG
:: JP.JpgEncodable px
=> [SaveOption JPG] -> JP.Image px -> BL.ByteString
encodeJPG [] =
JP.encodeDirectJpegAtQualityWithMetadata 100 M.mempty
encodeJPG (JPGQuality q:_) =
JP.encodeDirectJpegAtQualityWithMetadata q M.mempty
{-# INLINE encodeJPG #-}
instance Writable (Image VS Y Word8) JPG where
encode _ opts = encodeJPG opts . toJPImageY8
instance Writable (Image VS RGB Word8) JPG where
encode _ opts = encodeJPG opts . toJPImageRGB8
instance Writable (Image VS CMYK Word8) JPG where
encode _ opts = encodeJPG opts . toJPImageCMYK8
instance Writable (Image VS YCbCr Word8) JPG where
encode _ opts = encodeJPG opts . toJPImageYCbCr8
instance Writable (Image VS Y Double) JPG where
encode _ opts = encodeJPG opts . toJPImageYCbCr8 . toWord8I . toImageYCbCr
instance Writable (Image VS YA Double) JPG where
encode _ opts = encodeJPG opts . toJPImageYCbCr8 . toWord8I . toImageYCbCr
instance Writable (Image VS RGB Double) JPG where
encode _ opts = encodeJPG opts . toJPImageYCbCr8 . toWord8I . toImageYCbCr
instance Writable (Image VS RGBA Double) JPG where
encode _ opts = encodeJPG opts . toJPImageYCbCr8 . toWord8I . toImageYCbCr
data PNG = PNG deriving Show
instance ImageFormat PNG where
data SaveOption PNG
ext _ = ".png"
instance Readable (Image VS X Bit) PNG where
decode _ = fmap toImageBinary . jpImageY8ToImage <=< JP.decodePng
instance Readable (Image VS Y Word8) PNG where
decode _ = jpImageY8ToImage <=< JP.decodePng
instance Readable (Image VS Y Word16) PNG where
decode _ = jpImageY16ToImage <=< JP.decodePng
instance Readable (Image VS YA Word8) PNG where
decode _ = jpImageYA8ToImage <=< JP.decodePng
instance Readable (Image VS YA Word16) PNG where
decode _ = jpImageYA16ToImage <=< JP.decodePng
instance Readable (Image VS RGB Word8) PNG where
decode _ = jpImageRGB8ToImage <=< JP.decodePng
instance Readable (Image VS RGB Word16) PNG where
decode _ = jpImageRGB16ToImage <=< JP.decodePng
instance Readable (Image VS RGBA Word8) PNG where
decode _ = jpImageRGBA8ToImage <=< JP.decodePng
instance Readable (Image VS RGBA Word16) PNG where
decode _ = jpImageRGBA16ToImage <=< JP.decodePng
instance Readable (Image VS Y Double) PNG where
decode _ = fmap jpDynamicImageToImage . JP.decodePng
instance Readable (Image VS YA Double) PNG where
decode _ = fmap jpDynamicImageToImage . JP.decodePng
instance Readable (Image VS RGB Double) PNG where
decode _ = fmap jpDynamicImageToImage . JP.decodePng
instance Readable (Image VS RGBA Double) PNG where
decode _ = fmap jpDynamicImageToImage . JP.decodePng
instance Writable (Image VS X Bit) PNG where
encode _ _ = JP.encodePng . toJPImageY8 . fromImageBinary
instance Writable (Image VS Y Word8) PNG where
encode _ _ = JP.encodePng . toJPImageY8
instance Writable (Image VS Y Word16) PNG where
encode _ _ = JP.encodePng . toJPImageY16
instance Writable (Image VS YA Word8) PNG where
encode _ _ = JP.encodePng . toJPImageYA8
instance Writable (Image VS YA Word16) PNG where
encode _ _ = JP.encodePng . toJPImageYA16
instance Writable (Image VS RGB Word8) PNG where
encode _ _ = JP.encodePng . toJPImageRGB8
instance Writable (Image VS RGB Word16) PNG where
encode _ _ = JP.encodePng . toJPImageRGB16
instance Writable (Image VS RGBA Word8) PNG where
encode _ _ = JP.encodePng . toJPImageRGBA8
instance Writable (Image VS RGBA Word16) PNG where
encode _ _ = JP.encodePng . toJPImageRGBA16
instance Writable (Image VS Y Double) PNG where
encode _ _ = JP.encodePng . toJPImageY16 . toWord16I
instance Writable (Image VS YA Double) PNG where
encode _ _ = JP.encodePng . toJPImageYA16 . toWord16I
instance Writable (Image VS RGB Double) PNG where
encode _ _ = JP.encodePng . toJPImageRGB16 . toWord16I
instance Writable (Image VS RGBA Double) PNG where
encode _ _ = JP.encodePng . toJPImageRGBA16 . toWord16I
data TGA = TGA
instance ImageFormat TGA where
data SaveOption TGA
ext _ = ".tga"
instance Readable (Image VS X Bit) TGA where
decode _ = fmap toImageBinary . jpImageY8ToImage <=< JP.decodeTga
instance Readable (Image VS Y Word8) TGA where
decode _ = jpImageY8ToImage <=< JP.decodeTga
instance Readable (Image VS RGB Word8) TGA where
decode _ = jpImageRGB8ToImage <=< JP.decodeTga
instance Readable (Image VS RGBA Word8) TGA where
decode _ = jpImageRGBA8ToImage <=< JP.decodeTga
instance Readable (Image VS Y Double) TGA where
decode _ = fmap jpDynamicImageToImage . JP.decodeTga
instance Readable (Image VS YA Double) TGA where
decode _ = fmap jpDynamicImageToImage . JP.decodeTga
instance Readable (Image VS RGB Double) TGA where
decode _ = fmap jpDynamicImageToImage . JP.decodeTga
instance Readable (Image VS RGBA Double) TGA where
decode _ = fmap jpDynamicImageToImage . JP.decodeTga
instance Writable (Image VS X Bit) TGA where
encode _ _ = JP.encodeTga . toJPImageY8 . fromImageBinary
instance Writable (Image VS Y Word8) TGA where
encode _ _ = JP.encodeTga . toJPImageY8
instance Writable (Image VS RGB Word8) TGA where
encode _ _ = JP.encodeTga . toJPImageRGB8
instance Writable (Image VS RGBA Word8) TGA where
encode _ _ = JP.encodeTga . toJPImageRGBA8
instance Writable (Image VS Y Double) TGA where
encode _ _ = JP.encodeTga . toJPImageY8 . toWord8I
instance Writable (Image VS YA Double) TGA where
encode _ _ = JP.encodeTga . toJPImageY8 . toWord8I . toImageY
instance Writable (Image VS RGB Double) TGA where
encode _ _ = JP.encodeTga . toJPImageRGB8 . toWord8I
instance Writable (Image VS RGBA Double) TGA where
encode _ _ = JP.encodeTga . toJPImageRGBA8 . toWord8I
data TIF = TIF deriving Show
instance ImageFormat TIF where
data SaveOption TIF
ext _ = ".tif"
exts _ = [".tif", ".tiff"]
instance Readable (Image VS X Bit) TIF where
decode _ = fmap toImageBinary . jpImageY8ToImage <=< JP.decodeTiff
instance Readable (Image VS Y Word8) TIF where
decode _ = jpImageY8ToImage <=< JP.decodeTiff
instance Readable (Image VS Y Word16) TIF where
decode _ = jpImageY16ToImage <=< JP.decodeTiff
instance Readable (Image VS YA Word8) TIF where
decode _ = jpImageYA8ToImage <=< JP.decodeTiff
instance Readable (Image VS YA Word16) TIF where
decode _ = jpImageYA16ToImage <=< JP.decodeTiff
instance Readable (Image VS RGB Word8) TIF where
decode _ = jpImageRGB8ToImage <=< JP.decodeTiff
instance Readable (Image VS RGB Word16) TIF where
decode _ = jpImageRGB16ToImage <=< JP.decodeTiff
instance Readable (Image VS RGBA Word8) TIF where
decode _ = jpImageRGBA8ToImage <=< JP.decodeTiff
instance Readable (Image VS RGBA Word16) TIF where
decode _ = jpImageRGBA16ToImage <=< JP.decodeTiff
instance Readable (Image VS CMYK Word8) TIF where
decode _ = jpImageCMYK8ToImage <=< JP.decodeTiff
instance Readable (Image VS CMYK Word16) TIF where
decode _ = jpImageCMYK16ToImage <=< JP.decodeTiff
instance Readable (Image VS Y Double) TIF where
decode _ = fmap jpDynamicImageToImage . JP.decodeTiff
instance Readable (Image VS YA Double) TIF where
decode _ = fmap jpDynamicImageToImage . JP.decodeTiff
instance Readable (Image VS RGB Double) TIF where
decode _ = fmap jpDynamicImageToImage . JP.decodeTiff
instance Readable (Image VS RGBA Double) TIF where
decode _ = fmap jpDynamicImageToImage . JP.decodeTiff
instance Writable (Image VS Y Word8) TIF where
encode _ _ = JP.encodeTiff . toJPImageY8
instance Writable (Image VS Y Word16) TIF where
encode _ _ = JP.encodeTiff . toJPImageY16
instance Writable (Image VS YA Word8) TIF where
encode _ _ = JP.encodeTiff . toJPImageYA8
instance Writable (Image VS YA Word16) TIF where
encode _ _ = JP.encodeTiff . toJPImageYA16
instance Writable (Image VS RGB Word8) TIF where
encode _ _ = JP.encodeTiff . toJPImageRGB8
instance Writable (Image VS RGB Word16) TIF where
encode _ _ = JP.encodeTiff . toJPImageRGB16
instance Writable (Image VS RGBA Word8) TIF where
encode _ _ = JP.encodeTiff . toJPImageRGBA8
instance Writable (Image VS RGBA Word16) TIF where
encode _ _ = JP.encodeTiff . toJPImageRGBA16
instance Writable (Image VS YCbCr Word8) TIF where
encode _ _ = JP.encodeTiff . toJPImageYCbCr8
instance Writable (Image VS CMYK Word8) TIF where
encode _ _ = JP.encodeTiff . toJPImageCMYK8
instance Writable (Image VS CMYK Word16) TIF where
encode _ _ = JP.encodeTiff . toJPImageCMYK16
instance Writable (Image VS X Bit) TIF where
encode _ _ = JP.encodeTiff . toJPImageY8 . fromImageBinary
instance Writable (Image VS Y Double) TIF where
encode _ _ = JP.encodeTiff . toJPImageY16 . toWord16I
instance Writable (Image VS YA Double) TIF where
encode _ _ = JP.encodeTiff . toJPImageYA16 . toWord16I
instance Writable (Image VS RGB Double) TIF where
encode _ _ = JP.encodeTiff . toJPImageRGB16 . toWord16I
instance Writable (Image VS RGBA Double) TIF where
encode _ _ = JP.encodeTiff . toJPImageRGBA16 . toWord16I
instance Writable (Image VS YCbCr Double) TIF where
encode _ _ = JP.encodeTiff . toJPImageYCbCr8 . toWord8I
instance Writable (Image VS CMYK Double) TIF where
encode _ _ = JP.encodeTiff . toJPImageCMYK16 . toWord16I