JuicyPixels-blp-0.1.0.0: src/Codec/Picture/Blp/Internal/Convert.hs
module Codec.Picture.Blp.Internal.Convert(
toPngRepresentable
, toBlpUncompressable
, toBlpCMYK8
) where
import Codec.Picture
import Codec.Picture.Types
import Data.Word
toPngRepresentable :: DynamicImage -> DynamicImage
toPngRepresentable i = case i of
ImageY8 _ -> i
ImageY16 _ -> i
ImageYF p -> ImageRGB16 . convertFloatImage16 . promoteImage $ p
ImageYA8 _ -> i
ImageYA16 _ -> i
ImageRGB8 _ -> i
ImageRGB16 _ -> i
ImageRGBF p -> ImageRGB16 . convertFloatImage16 $ p
ImageRGBA8 _ -> i
ImageRGBA16 _ -> i
ImageYCbCr8 p -> ImageRGB8 . convertImage $ p
ImageCMYK8 p -> ImageRGBA8 . convertCMYK8Image $ p
ImageCMYK16 p -> ImageRGBA16 . convertCMYK16Image $ p
toBlpUncompressable :: DynamicImage -> Image PixelRGBA8
toBlpUncompressable i = case i of
ImageY8 p -> toBlpRGB8 (promoteImage p :: Image PixelRGB8)
ImageY16 p -> toBlpRGB8 (dropBits (promoteImage p :: Image PixelRGB16) :: Image PixelRGB8)
ImageYF p -> toBlpRGB8 (convertFloatImage8 (promoteImage p :: Image PixelRGBF) :: Image PixelRGB8)
ImageYA8 p -> toBlpRGBA8 (promoteImage p :: Image PixelRGBA8)
ImageYA16 p -> toBlpRGBA8 (dropBitsA (promoteImage p :: Image PixelRGBA16) :: Image PixelRGBA8)
ImageRGB8 p -> toBlpRGB8 p
ImageRGB16 p -> toBlpRGB8 (dropBits p :: Image PixelRGB8)
ImageRGBF p -> toBlpRGB8 (convertFloatImage8 p :: Image PixelRGB8)
ImageRGBA8 p -> toBlpRGBA8 p
ImageRGBA16 p -> toBlpRGBA8 (dropBitsA p :: Image PixelRGBA8)
ImageYCbCr8 p -> toBlpRGB8 (convertImage p :: Image PixelRGB8)
ImageCMYK8 p -> toBlpRGB8 (convertImage p :: Image PixelRGB8)
ImageCMYK16 p -> toBlpRGB8 (dropBits (convertImage p :: Image PixelRGB16) :: Image PixelRGB8)
dropBits :: Image PixelRGB16 -> Image PixelRGB8
dropBits = pixelMap $ \(PixelRGB16 r g b) -> PixelRGB8 (f r) (f g) (f b)
where
f :: Word16 -> Word8
f x = round $ 255 * (fromIntegral x :: Double) / 65535
dropBitsA :: Image PixelRGBA16 -> Image PixelRGBA8
dropBitsA = pixelMap $ \(PixelRGBA16 r g b a) -> PixelRGBA8 (f r) (f g) (f b) (f a)
where
f :: Word16 -> Word8
f x = round $ 255 * (fromIntegral x :: Double) / 65535
convertFloatImage8 :: Image PixelRGBF -> Image PixelRGB8
convertFloatImage8 = pixelMap convert
where
convert (PixelRGBF rf gf bf) = PixelRGB8
(round $ 255 * rf)
(round $ 255 * gf)
(round $ 255 * bf)
convertFloatImage16 :: Image PixelRGBF -> Image PixelRGB16
convertFloatImage16 = pixelMap convert
where
convert (PixelRGBF rf gf bf) = PixelRGB16
(round $ 65535 * rf)
(round $ 65535 * gf)
(round $ 65535 * bf)
convertCMYK8Image :: Image PixelCMYK8 -> Image PixelRGBA8
convertCMYK8Image = pixelMap convert
where
clampWord8 = fromIntegral . max 0 . min 255 . (`div` 256)
convert (PixelCMYK8 c m y k) =
PixelRGBA8 (clampWord8 r) (clampWord8 g) (clampWord8 b) k
where
ik :: Int
ik = fromIntegral k
r = fromIntegral y * ik
g = fromIntegral m * ik
b = fromIntegral c * ik
toBlpCMYK8 :: Image PixelRGBA8 -> Image PixelCMYK8
toBlpCMYK8 = pixelMap convert
where
clampWord8 = fromIntegral . max 0 . min 255
convert (PixelRGBA8 r g b a) = PixelCMYK8 (clampWord8 c) (clampWord8 m) (clampWord8 y) a
where
ik = fromIntegral a :: Double
c, m, y :: Int
c = round $ 256 * fromIntegral b / ik
m = round $ 256 * fromIntegral g / ik
y = round $ 256 * fromIntegral r / ik
toBlpRGBA8 :: Image PixelRGBA8 -> Image PixelRGBA8
toBlpRGBA8 = pixelMap convert
where
convert (PixelRGBA8 r g b a) = PixelRGBA8 b g r a
toBlpRGB8 :: Image PixelRGB8 -> Image PixelRGBA8
toBlpRGB8 = pixelMap convert
where
convert (PixelRGB8 r g b) = PixelRGBA8 b g r 0
convertCMYK16Image :: Image PixelCMYK16 -> Image PixelRGBA16
convertCMYK16Image = pixelMap convert
where
convert (PixelCMYK16 c m y k) =
PixelRGBA16 (clampWord16 r) (clampWord16 g) (clampWord16 b) 65535
where
clampWord16 = fromIntegral . max 0 . min 65535 . (`div` 65535)
ik :: Int
ik = fromIntegral k
r = fromIntegral y * ik
g = fromIntegral m * ik
b = fromIntegral c * ik