位图 - 解析二进制数据

Attoparsec 使得解析二进制数据变得微不足道。假设这些定义:

import           Data.Attoparsec.ByteString (Parser, eitherResult, parse, take)
import           Data.Binary.Get            (getWord32le, runGet)
import           Data.ByteString            (ByteString, readFile)
import           Data.ByteString.Char8      (unpack)
import           Data.ByteString.Lazy       (fromStrict)
import           Prelude                    hiding (readFile, take)

-- The DIB section from a bitmap header
data DIB = BM | BA | CI | CP | IC | PT
           deriving (Show, Read)

type Reserved = ByteString

-- The entire bitmap header
data Header = Header DIB Int Reserved Reserved Int
              deriving (Show)

我们可以轻松地解析位图文件中的标题。这里,我们有 4 个解析器函数,它们代表位图文件中的标题部分:

首先,可以通过取前 2 个字节来读取 DIB 部分

dibP::Parser DIB
dibP = read . unpack <$> take 2

同样,也可以轻松读取位图的大小,保留部分和像素偏移:

sizeP::Parser Int
sizeP = fromIntegral . runGet getWord32le . fromStrict <$> take 4

reservedP::Parser Reserved
reservedP = take 2

addressP::Parser Int
addressP = fromIntegral . runGet getWord32le . fromStrict <$> take 4

然后可以将其组合成整个标头的更大的解析器函数:

bitmapHeader::Parser Header
bitmapHeader = do
    dib <- dibP
    sz <- sizeP
    reservedP
    reservedP
    offset <- addressP
    return $ Header dib sz "" "" offset