packages feed

binary-file-0.12.8: examples/readPNG.hs

{-# LANGUAGE QuasiQuotes, TypeFamilies, FlexibleInstances #-}

import File.Binary
import File.Binary.Data.BigEndian
import System.Environment
import Data.Word
import qualified Data.ByteString as BS

main = do
	[fin, fout] <- getArgs
	cnt <- readBinaryFile fin
	let (png, rest) = readPNG () cnt
	print $ png
	writeBinaryFile fout $ writePNG () png

test = readPNG () `fmap` readBinaryFile "tmp/out.png"

instance RetType Word32 where
	type Argument Word32 = Int
	fromType n = rev . fi n . fromIntegral
	toType n s = (fromIntegral $ ti $ rev $ tk n s, dp n s)

instance RetType Chank where
	type Argument Chank = ()
	fromType = writeChank
	toType = readChank

instance RetType (Int, Int, Int) where
	type Argument (Int, Int, Int) = ()
	fromType _ (b, g, r) = cc [fromType 1 b, fromType 1 g, fromType 1 r]
	toType _ s = let
		(b, rest) = toType 1 s
		(g, rest') = toType 1 rest
		(r, rest'') = toType 1 rest' in
		((b, g, r), rest'')

[binary|

PNG

1: 0x89
3: "PNG"
2: "\r\n"
1: "\SUB"
1: "\n"
((), Nothing)<[Chank]>: chanks

|]

data ChankBody
	= ChankIHDR IHDR
	| ChankGAMA GAMA
	| ChankSRGB SRGB
	| ChankCHRM CHRM
	| ChankPLTE PLTE
	| ChankBKGD BKGD
	| ChankIDAT IDAT
	| ChankTEXT TEXT
	| ChankIEND IEND
	| Others String
	deriving Show

instance RetType ChankBody where
	type Argument ChankBody = (Int, String)
	fromType _ (ChankIHDR ihdr) = writeIHDR () ihdr
	fromType _ (ChankGAMA gama) = writeGAMA () gama
	fromType _ (ChankSRGB srgb) = writeSRGB () srgb
	fromType _ (ChankCHRM chrm) = writeCHRM () chrm
	fromType (n, _) (ChankPLTE plte) = writePLTE n plte
	fromType _ (ChankBKGD bkgd) = writeBKGD () bkgd
	fromType (n, _) (ChankIDAT idat) = writeIDAT n idat
	fromType (n, _) (ChankTEXT text) = writeTEXT n text
	fromType _ (ChankIEND iend) = writeIEND () iend
	fromType (n, _) (Others str) = fromType ((), Just n) str
	toType (_, "IHDR") str = let (ihdr, rest) = readIHDR () str in
		(ChankIHDR ihdr, rest)
	toType (_, "gAMA") str = let (gama, rest) = readGAMA () str in
		(ChankGAMA gama, rest)
	toType (_, "sRGB") str = let (srgb, rest) = readSRGB () str in
		(ChankSRGB srgb, rest)
	toType (_, "cHRM") str = let (chrm, rest) = readCHRM () str in
		(ChankCHRM chrm, rest)
	toType (n, "PLTE") str = let (plte, rest) = readPLTE n str in
		(ChankPLTE plte, rest)
	toType (_, "bKGD") str = let (bkgd, rest) = readBKGD () str in
		(ChankBKGD bkgd, rest)
	toType (n, "IDAT") str = let (idat, rest) = readIDAT n str in
		(ChankIDAT idat, rest)
	toType (n, "tEXt") str = let (text, rest) = readTEXT n str in
		(ChankTEXT text, rest)
	toType (_, "IEND") str = let (iend, rest) = readIEND () str in
		(ChankIEND iend, rest)
	toType (n, _) str = let (others, rest) = toType ((), Just n) str in
		(Others others, rest)

[binary|

Chank

4: chankSize
((), Just 4)<String>: chankName
(chankSize, chankName)<ChankBody>: chankData
-- ((), Just chankSize)<String>: chankData
4<Word32>:chankCRC

|]

[binary|

IHDR

4: width
4: height
1: depth
1: colorType
1: compressionType
1: filterType
1: interlaceType

|]

[binary|

GAMA

4: gamma

|]

[binary|

SRGB

1: srgb

|]

[binary|

CHRM

4: chrm1
4: chrm2
4: chrm3
4: chrm4
4: chrm5
4: chrm6
4: chrm7
4: chrm8

|]

[binary|

PLTE

<Int>

((), Just (arg `div` 3))<[(Int, Int, Int)]>: colors

|]

[binary|

BKGD

1: bkgd

|]

[binary|

IDAT

<Int>

arg<BS.ByteString>: idat

|]

[binary|

TEXT

<Int>

((), Just arg)<String>: text

|]

[binary|

IEND

|]