packages feed

png-file-0.0.1.0: src/File/Binary/PNG/Chunks/CRC.hs

{-# LANGUAGE OverloadedStrings #-}

module File.Binary.PNG.Chunks.CRC (checkCRC, crc) where

import Prelude hiding (reverse)
import Data.Array (Array, listArray, (!))
import Data.Word (Word32)
import Data.Bits ((.&.), xor, shiftR)
import Data.ByteString.Lazy (ByteString, cons', append, reverse)
import qualified Data.ByteString.Lazy as BSL (foldl)
import Data.ByteString.Lazy.Char8 ()

--------------------------------------------------------------------------------

checkCRC :: ByteString -> ByteString -> Bool
checkCRC str c = crc (str `append` reverse c) == "\x21\x44\xdf\x1c"

crc :: ByteString -> ByteString
crc = reverse . word32ToBS . xor 0xffffffff . BSL.foldl crc' 0xffffffff
	where
	crc' c x = table ! (c .&. 0xff `xor` fromIntegral x) `xor` shiftR c 8

table :: Array Word32 Word32
table = listArray (0, 255) $ map (\n -> iterate crc8bit n !! 8) [0 .. 255]

crc8bit :: Word32 -> Word32
crc8bit c
	| c .&. 1 == 0 = shiftR c 1
	| otherwise = 0xedb88320 `xor` shiftR c 1

word32ToBS :: Word32 -> ByteString
word32ToBS 0 = ""
word32ToBS w = fromIntegral (w .&. 0xff) `cons'` word32ToBS (w `shiftR` 8)