{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Codec.Picture.Png.Internal.Export( PngSavable( .. )
, PngPaletteSaveable( .. )
, writePng
, encodeDynamicPng
, writeDynamicPng
) where
#if !MIN_VERSION_base(4,8,0)
import Data.Monoid( mempty )
#endif
import Control.Monad( forM_ )
import Control.Monad.ST( ST, runST )
import Data.Bits( unsafeShiftR, (.&.) )
import Data.Binary( encode )
#if !MIN_VERSION_base(4,11,0)
import Data.Monoid( (<>) )
#endif
import Data.Word(Word8, Word16)
import qualified Codec.Compression.Zlib as Z
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as Lb
import qualified Data.Vector.Storable as VS
import qualified Data.Vector.Storable.Mutable as M
import Codec.Picture.Types
import Codec.Picture.Png.Internal.Type
import Codec.Picture.Png.Internal.Metadata
import Codec.Picture.Metadata( Metadatas )
import Codec.Picture.VectorByteConversion( blitVector, toByteString )
class PngPaletteSaveable a where
encodePalettedPng :: Image a -> Image Pixel8 -> Either String Lb.ByteString
encodePalettedPng = forall a.
PngPaletteSaveable a =>
Metadatas -> Image a -> Image Pixel8 -> Either String ByteString
encodePalettedPngWithMetadata forall a. Monoid a => a
mempty
encodePalettedPngWithMetadata :: Metadatas -> Image a -> Image Pixel8 -> Either String Lb.ByteString
instance PngPaletteSaveable PixelRGB8 where
encodePalettedPngWithMetadata :: Metadatas
-> Image PixelRGB8 -> Image Pixel8 -> Either String ByteString
encodePalettedPngWithMetadata Metadatas
metas Image PixelRGB8
pal Image Pixel8
img
| Int
w forall a. Ord a => a -> a -> Bool
<= Int
0 Bool -> Bool -> Bool
|| Int
w forall a. Ord a => a -> a -> Bool
> Int
256 Bool -> Bool -> Bool
|| Int
h forall a. Eq a => a -> a -> Bool
/= Int
1 = forall a b. a -> Either a b
Left String
"Invalid palette"
| forall a. Storable a => (a -> Bool) -> Vector a -> Bool
VS.any Pixel8 -> Bool
isTooBig forall a b. (a -> b) -> a -> b
$ forall a. Image a -> Vector (PixelBaseComponent a)
imageData Image Pixel8
img =
forall a b. a -> Either a b
Left String
"Image contains indexes absent from the palette"
| Bool
otherwise = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall px.
(Pixel px, PixelBaseComponent px ~ Pixel8) =>
Maybe (Image PixelRGB8)
-> Maybe PaletteAlpha
-> PngImageType
-> Metadatas
-> Image px
-> ByteString
genericEncodePng (forall a. a -> Maybe a
Just Image PixelRGB8
pal) forall a. Maybe a
Nothing PngImageType
PngIndexedColor Metadatas
metas Image Pixel8
img
where w :: Int
w = forall a. Image a -> Int
imageWidth Image PixelRGB8
pal
h :: Int
h = forall a. Image a -> Int
imageHeight Image PixelRGB8
pal
isTooBig :: Pixel8 -> Bool
isTooBig Pixel8
v = forall a b. (Integral a, Num b) => a -> b
fromIntegral Pixel8
v forall a. Ord a => a -> a -> Bool
>= Int
w
instance PngPaletteSaveable PixelRGBA8 where
encodePalettedPngWithMetadata :: Metadatas
-> Image PixelRGBA8 -> Image Pixel8 -> Either String ByteString
encodePalettedPngWithMetadata Metadatas
metas Image PixelRGBA8
pal Image Pixel8
img
| Int
w forall a. Ord a => a -> a -> Bool
<= Int
0 Bool -> Bool -> Bool
|| Int
w forall a. Ord a => a -> a -> Bool
> Int
256 Bool -> Bool -> Bool
|| Int
h forall a. Eq a => a -> a -> Bool
/= Int
1 = forall a b. a -> Either a b
Left String
"Invalid palette"
| forall a. Storable a => (a -> Bool) -> Vector a -> Bool
VS.any Pixel8 -> Bool
isTooBig forall a b. (a -> b) -> a -> b
$ forall a. Image a -> Vector (PixelBaseComponent a)
imageData Image Pixel8
img =
forall a b. a -> Either a b
Left String
"Image contains indexes absent from the palette"
| Bool
otherwise = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall px.
(Pixel px, PixelBaseComponent px ~ Pixel8) =>
Maybe (Image PixelRGB8)
-> Maybe PaletteAlpha
-> PngImageType
-> Metadatas
-> Image px
-> ByteString
genericEncodePng (forall a. a -> Maybe a
Just Image PixelRGB8
opaquePalette) (forall a. a -> Maybe a
Just Vector (PixelBaseComponent Pixel8)
alphaPal) PngImageType
PngIndexedColor Metadatas
metas Image Pixel8
img
where
w :: Int
w = forall a. Image a -> Int
imageWidth Image PixelRGBA8
pal
h :: Int
h = forall a. Image a -> Int
imageHeight Image PixelRGBA8
pal
opaquePalette :: Image PixelRGB8
opaquePalette = forall a b. TransparentPixel a b => Image a -> Image b
dropAlphaLayer Image PixelRGBA8
pal
alphaPal :: Vector (PixelBaseComponent Pixel8)
alphaPal = forall a. Image a -> Vector (PixelBaseComponent a)
imageData forall a b. (a -> b) -> a -> b
$ forall px plane.
(Pixel px, Pixel (PixelBaseComponent px),
PixelBaseComponent (PixelBaseComponent px) ~ PixelBaseComponent px,
ColorPlane px plane) =>
plane -> Image px -> Image (PixelBaseComponent px)
extractComponent PlaneAlpha
PlaneAlpha Image PixelRGBA8
pal
isTooBig :: Pixel8 -> Bool
isTooBig Pixel8
v = forall a b. (Integral a, Num b) => a -> b
fromIntegral Pixel8
v forall a. Ord a => a -> a -> Bool
>= Int
w
class PngSavable a where
encodePng :: Image a -> Lb.ByteString
encodePng = forall a. PngSavable a => Metadatas -> Image a -> ByteString
encodePngWithMetadata forall a. Monoid a => a
mempty
encodePngWithMetadata :: Metadatas -> Image a -> Lb.ByteString
preparePngHeader :: Image a -> PngImageType -> Word8 -> PngIHdr
(Image { imageWidth :: forall a. Image a -> Int
imageWidth = Int
w, imageHeight :: forall a. Image a -> Int
imageHeight = Int
h }) PngImageType
imgType Pixel8
depth = PngIHdr
{ width :: Word32
width = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
w
, height :: Word32
height = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
h
, bitDepth :: Pixel8
bitDepth = Pixel8
depth
, colourType :: PngImageType
colourType = PngImageType
imgType
, compressionMethod :: Pixel8
compressionMethod = Pixel8
0
, filterMethod :: Pixel8
filterMethod = Pixel8
0
, interlaceMethod :: PngInterlaceMethod
interlaceMethod = PngInterlaceMethod
PngNoInterlace
}
writePng :: (PngSavable pixel) => FilePath -> Image pixel -> IO ()
writePng :: forall pixel. PngSavable pixel => String -> Image pixel -> IO ()
writePng String
path Image pixel
img = String -> ByteString -> IO ()
Lb.writeFile String
path forall a b. (a -> b) -> a -> b
$ forall a. PngSavable a => Image a -> ByteString
encodePng Image pixel
img
endChunk :: PngRawChunk
endChunk :: PngRawChunk
endChunk = ByteString -> ByteString -> PngRawChunk
mkRawChunk ByteString
iENDSignature forall a. Monoid a => a
mempty
prepareIDatChunk :: Lb.ByteString -> PngRawChunk
prepareIDatChunk :: ByteString -> PngRawChunk
prepareIDatChunk = ByteString -> ByteString -> PngRawChunk
mkRawChunk ByteString
iDATSignature
genericEncode16BitsPng :: forall px. (Pixel px, PixelBaseComponent px ~ Word16)
=> PngImageType -> Metadatas -> Image px -> Lb.ByteString
genericEncode16BitsPng :: forall px.
(Pixel px, PixelBaseComponent px ~ Pixel16) =>
PngImageType -> Metadatas -> Image px -> ByteString
genericEncode16BitsPng PngImageType
imgKind Metadatas
metas
image :: Image px
image@(Image { imageWidth :: forall a. Image a -> Int
imageWidth = Int
w, imageHeight :: forall a. Image a -> Int
imageHeight = Int
h, imageData :: forall a. Image a -> Vector (PixelBaseComponent a)
imageData = Vector (PixelBaseComponent px)
arr }) =
forall a. Binary a => a -> ByteString
encode PngRawImage { header :: PngIHdr
header = PngIHdr
hdr
, chunks :: [PngRawChunk]
chunks = Metadatas -> [PngRawChunk]
encodeMetadatas Metadatas
metas
forall a. Semigroup a => a -> a -> a
<> [ ByteString -> PngRawChunk
prepareIDatChunk ByteString
imgEncodedData
, PngRawChunk
endChunk
]
}
where hdr :: PngIHdr
hdr = forall a. Image a -> PngImageType -> Pixel8 -> PngIHdr
preparePngHeader Image px
image PngImageType
imgKind Pixel8
16
zero :: ByteString
zero = Pixel8 -> ByteString
B.singleton Pixel8
0
compCount :: Int
compCount = forall a. Pixel a => a -> Int
componentCount (forall a. HasCallStack => a
undefined :: px)
lineSize :: Int
lineSize = Int
compCount forall a. Num a => a -> a -> a
* Int
w
blitToByteString :: PaletteAlpha -> ByteString
blitToByteString PaletteAlpha
vec = PaletteAlpha -> Int -> Int -> ByteString
blitVector PaletteAlpha
vec Int
0 (Int
lineSize forall a. Num a => a -> a -> a
* Int
2)
encodeLine :: Int -> ByteString
encodeLine Int
line = PaletteAlpha -> ByteString
blitToByteString forall a b. (a -> b) -> a -> b
$ forall a. (forall s. ST s a) -> a
runST forall a b. (a -> b) -> a -> b
$ do
STVector s Pixel8
finalVec <- forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> m (MVector (PrimState m) a)
M.new forall a b. (a -> b) -> a -> b
$ Int
lineSize forall a. Num a => a -> a -> a
* Int
2 :: ST s (M.STVector s Word8)
let baseIndex :: Int
baseIndex = Int
line forall a. Num a => a -> a -> a
* Int
lineSize
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0 .. Int
lineSize forall a. Num a => a -> a -> a
- Int
1] forall a b. (a -> b) -> a -> b
$ \Int
ix -> do
let v :: Pixel16
v = Vector (PixelBaseComponent px)
arr forall a. Storable a => Vector a -> Int -> a
`VS.unsafeIndex` (Int
baseIndex forall a. Num a => a -> a -> a
+ Int
ix)
high :: Pixel8
high = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (Pixel16
v forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
8) forall a. Bits a => a -> a -> a
.&. Pixel16
0xFF
low :: Pixel8
low = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Pixel16
v forall a. Bits a => a -> a -> a
.&. Pixel16
0xFF
(STVector s Pixel8
finalVec forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
ix forall a. Num a => a -> a -> a
* Int
2 forall a. Num a => a -> a -> a
+ Int
0)) Pixel8
high
(STVector s Pixel8
finalVec forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
`M.unsafeWrite` (Int
ix forall a. Num a => a -> a -> a
* Int
2 forall a. Num a => a -> a -> a
+ Int
1)) Pixel8
low
forall a (m :: * -> *).
(Storable a, PrimMonad m) =>
MVector (PrimState m) a -> m (Vector a)
VS.unsafeFreeze STVector s Pixel8
finalVec
imgEncodedData :: ByteString
imgEncodedData = ByteString -> ByteString
Z.compress forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
Lb.fromChunks
forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[ByteString
zero, Int -> ByteString
encodeLine Int
line] | Int
line <- [Int
0 .. Int
h forall a. Num a => a -> a -> a
- Int
1]]
preparePalette :: Palette -> PngRawChunk
preparePalette :: Image PixelRGB8 -> PngRawChunk
preparePalette Image PixelRGB8
pal = PngRawChunk
{ chunkLength :: Word32
chunkLength = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall a. Image a -> Int
imageWidth Image PixelRGB8
pal forall a. Num a => a -> a -> a
* Int
3
, chunkType :: ByteString
chunkType = ByteString
pLTESignature
, chunkCRC :: Word32
chunkCRC = [ByteString] -> Word32
pngComputeCrc [ByteString
pLTESignature, ByteString
binaryData]
, chunkData :: ByteString
chunkData = ByteString
binaryData
}
where binaryData :: ByteString
binaryData = [ByteString] -> ByteString
Lb.fromChunks [forall a. Storable a => Vector a -> ByteString
toByteString forall a b. (a -> b) -> a -> b
$ forall a. Image a -> Vector (PixelBaseComponent a)
imageData Image PixelRGB8
pal]
preparePaletteAlpha :: VS.Vector Pixel8 -> PngRawChunk
preparePaletteAlpha :: PaletteAlpha -> PngRawChunk
preparePaletteAlpha PaletteAlpha
alphaPal = PngRawChunk
{ chunkLength :: Word32
chunkLength = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Vector a -> Int
VS.length PaletteAlpha
alphaPal
, chunkType :: ByteString
chunkType = ByteString
tRNSSignature
, chunkCRC :: Word32
chunkCRC = [ByteString] -> Word32
pngComputeCrc [ByteString
tRNSSignature, ByteString
binaryData]
, chunkData :: ByteString
chunkData = ByteString
binaryData
}
where binaryData :: ByteString
binaryData = [ByteString] -> ByteString
Lb.fromChunks [forall a. Storable a => Vector a -> ByteString
toByteString PaletteAlpha
alphaPal]
type PaletteAlpha = VS.Vector Pixel8
genericEncodePng :: forall px. (Pixel px, PixelBaseComponent px ~ Word8)
=> Maybe Palette
-> Maybe PaletteAlpha
-> PngImageType -> Metadatas -> Image px
-> Lb.ByteString
genericEncodePng :: forall px.
(Pixel px, PixelBaseComponent px ~ Pixel8) =>
Maybe (Image PixelRGB8)
-> Maybe PaletteAlpha
-> PngImageType
-> Metadatas
-> Image px
-> ByteString
genericEncodePng Maybe (Image PixelRGB8)
palette Maybe PaletteAlpha
palAlpha PngImageType
imgKind Metadatas
metas
image :: Image px
image@(Image { imageWidth :: forall a. Image a -> Int
imageWidth = Int
w, imageHeight :: forall a. Image a -> Int
imageHeight = Int
h, imageData :: forall a. Image a -> Vector (PixelBaseComponent a)
imageData = Vector (PixelBaseComponent px)
arr }) =
forall a. Binary a => a -> ByteString
encode PngRawImage { header :: PngIHdr
header = PngIHdr
hdr
, chunks :: [PngRawChunk]
chunks = Metadatas -> [PngRawChunk]
encodeMetadatas Metadatas
metas
forall a. Semigroup a => a -> a -> a
<> [PngRawChunk]
paletteChunk
forall a. Semigroup a => a -> a -> a
<> [PngRawChunk]
transpChunk
forall a. Semigroup a => a -> a -> a
<> [ ByteString -> PngRawChunk
prepareIDatChunk ByteString
imgEncodedData
, PngRawChunk
endChunk
]}
where
hdr :: PngIHdr
hdr = forall a. Image a -> PngImageType -> Pixel8 -> PngIHdr
preparePngHeader Image px
image PngImageType
imgKind Pixel8
8
zero :: ByteString
zero = Pixel8 -> ByteString
B.singleton Pixel8
0
compCount :: Int
compCount = forall a. Pixel a => a -> Int
componentCount (forall a. HasCallStack => a
undefined :: px)
paletteChunk :: [PngRawChunk]
paletteChunk = case Maybe (Image PixelRGB8)
palette of
Maybe (Image PixelRGB8)
Nothing -> []
Just Image PixelRGB8
p -> [Image PixelRGB8 -> PngRawChunk
preparePalette Image PixelRGB8
p]
transpChunk :: [PngRawChunk]
transpChunk = case Maybe PaletteAlpha
palAlpha of
Maybe PaletteAlpha
Nothing -> []
Just PaletteAlpha
p -> [PaletteAlpha -> PngRawChunk
preparePaletteAlpha PaletteAlpha
p]
lineSize :: Int
lineSize = Int
compCount forall a. Num a => a -> a -> a
* Int
w
encodeLine :: Int -> ByteString
encodeLine Int
line = PaletteAlpha -> Int -> Int -> ByteString
blitVector Vector (PixelBaseComponent px)
arr (Int
line forall a. Num a => a -> a -> a
* Int
lineSize) Int
lineSize
imgEncodedData :: ByteString
imgEncodedData = ByteString -> ByteString
Z.compress
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
Lb.fromChunks
forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[ByteString
zero, Int -> ByteString
encodeLine Int
line] | Int
line <- [Int
0 .. Int
h forall a. Num a => a -> a -> a
- Int
1]]
instance PngSavable PixelRGBA8 where
encodePngWithMetadata :: Metadatas -> Image PixelRGBA8 -> ByteString
encodePngWithMetadata = forall px.
(Pixel px, PixelBaseComponent px ~ Pixel8) =>
Maybe (Image PixelRGB8)
-> Maybe PaletteAlpha
-> PngImageType
-> Metadatas
-> Image px
-> ByteString
genericEncodePng forall a. Maybe a
Nothing forall a. Maybe a
Nothing PngImageType
PngTrueColourWithAlpha
instance PngSavable PixelRGB8 where
encodePngWithMetadata :: Metadatas -> Image PixelRGB8 -> ByteString
encodePngWithMetadata = forall px.
(Pixel px, PixelBaseComponent px ~ Pixel8) =>
Maybe (Image PixelRGB8)
-> Maybe PaletteAlpha
-> PngImageType
-> Metadatas
-> Image px
-> ByteString
genericEncodePng forall a. Maybe a
Nothing forall a. Maybe a
Nothing PngImageType
PngTrueColour
instance PngSavable Pixel8 where
encodePngWithMetadata :: Metadatas -> Image Pixel8 -> ByteString
encodePngWithMetadata = forall px.
(Pixel px, PixelBaseComponent px ~ Pixel8) =>
Maybe (Image PixelRGB8)
-> Maybe PaletteAlpha
-> PngImageType
-> Metadatas
-> Image px
-> ByteString
genericEncodePng forall a. Maybe a
Nothing forall a. Maybe a
Nothing PngImageType
PngGreyscale
instance PngSavable PixelYA8 where
encodePngWithMetadata :: Metadatas -> Image PixelYA8 -> ByteString
encodePngWithMetadata = forall px.
(Pixel px, PixelBaseComponent px ~ Pixel8) =>
Maybe (Image PixelRGB8)
-> Maybe PaletteAlpha
-> PngImageType
-> Metadatas
-> Image px
-> ByteString
genericEncodePng forall a. Maybe a
Nothing forall a. Maybe a
Nothing PngImageType
PngGreyscaleWithAlpha
instance PngSavable PixelYA16 where
encodePngWithMetadata :: Metadatas -> Image PixelYA16 -> ByteString
encodePngWithMetadata = forall px.
(Pixel px, PixelBaseComponent px ~ Pixel16) =>
PngImageType -> Metadatas -> Image px -> ByteString
genericEncode16BitsPng PngImageType
PngGreyscaleWithAlpha
instance PngSavable Pixel16 where
encodePngWithMetadata :: Metadatas -> Image Pixel16 -> ByteString
encodePngWithMetadata = forall px.
(Pixel px, PixelBaseComponent px ~ Pixel16) =>
PngImageType -> Metadatas -> Image px -> ByteString
genericEncode16BitsPng PngImageType
PngGreyscale
instance PngSavable PixelRGB16 where
encodePngWithMetadata :: Metadatas -> Image PixelRGB16 -> ByteString
encodePngWithMetadata = forall px.
(Pixel px, PixelBaseComponent px ~ Pixel16) =>
PngImageType -> Metadatas -> Image px -> ByteString
genericEncode16BitsPng PngImageType
PngTrueColour
instance PngSavable PixelRGBA16 where
encodePngWithMetadata :: Metadatas -> Image PixelRGBA16 -> ByteString
encodePngWithMetadata = forall px.
(Pixel px, PixelBaseComponent px ~ Pixel16) =>
PngImageType -> Metadatas -> Image px -> ByteString
genericEncode16BitsPng PngImageType
PngTrueColourWithAlpha
writeDynamicPng :: FilePath -> DynamicImage -> IO (Either String Bool)
writeDynamicPng :: String -> DynamicImage -> IO (Either String Bool)
writeDynamicPng String
path DynamicImage
img = case DynamicImage -> Either String ByteString
encodeDynamicPng DynamicImage
img of
Left String
err -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left String
err
Right ByteString
b -> String -> ByteString -> IO ()
Lb.writeFile String
path ByteString
b forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. b -> Either a b
Right Bool
True)
encodeDynamicPng :: DynamicImage -> Either String Lb.ByteString
encodeDynamicPng :: DynamicImage -> Either String ByteString
encodeDynamicPng (ImageRGB8 Image PixelRGB8
img) = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a. PngSavable a => Image a -> ByteString
encodePng Image PixelRGB8
img
encodeDynamicPng (ImageRGBA8 Image PixelRGBA8
img) = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a. PngSavable a => Image a -> ByteString
encodePng Image PixelRGBA8
img
encodeDynamicPng (ImageY8 Image Pixel8
img) = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a. PngSavable a => Image a -> ByteString
encodePng Image Pixel8
img
encodeDynamicPng (ImageY16 Image Pixel16
img) = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a. PngSavable a => Image a -> ByteString
encodePng Image Pixel16
img
encodeDynamicPng (ImageYA8 Image PixelYA8
img) = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a. PngSavable a => Image a -> ByteString
encodePng Image PixelYA8
img
encodeDynamicPng (ImageYA16 Image PixelYA16
img) = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a. PngSavable a => Image a -> ByteString
encodePng Image PixelYA16
img
encodeDynamicPng (ImageRGB16 Image PixelRGB16
img) = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a. PngSavable a => Image a -> ByteString
encodePng Image PixelRGB16
img
encodeDynamicPng (ImageRGBA16 Image PixelRGBA16
img) = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a. PngSavable a => Image a -> ByteString
encodePng Image PixelRGBA16
img
encodeDynamicPng DynamicImage
_ = forall a b. a -> Either a b
Left String
"Unsupported image format for PNG export"