我正在尝试使用Haskell解析二进制格式(PES):
import qualified Data.ByteString.Lazy as BL
import Data.Word
import Data.Word.Word24
import qualified Data.ByteString.Lazy.Char8 as L8
data Stitch = MyCoord Int Int deriving (Eq, Show)
data PESFile = PESFile {
pecstart :: Word24
, width :: Int
, height :: Int
, numColors :: Int
, header :: String
, stitches :: [Stitch]
} deriving (Eq, Show)
readPES :: BL.ByteString -> Maybe PESFile
readPES bs =
let s = L8.drop 7 bs
pecstart = L8.readInt s in
case pecstart of
Nothing -> Nothing
Just (offset,rest) -> Just (PESFile offset 1 1 1 "#PES" [])
main = do
input <- BL.getContents
print $ readPES input
我需要阅读pecstart来获取其他数据的偏移量(宽度,高度和高度) 但这对我不起作用,因为我需要读取24位值,而ByteString包似乎没有24位版本。
我应该使用不同的方法吗? Data.Binary软件包似乎适用于简单格式,但我不确定它是如何工作的,因为你必须读取一个值来查找文件中其他数据的偏移量。我缺少的东西?
答案 0 :(得分:6)
好吧,你可以通过索引3个字节来解析24位值(这里是网络顺序):
import qualified Data.ByteString as B
import Data.ByteString (ByteString, index)
import Data.Bits
import Data.Int
import Data.Word
type Int24 = Int32
readInt24 :: ByteString -> (Int24, ByteString)
readInt24 bs = (roll [a,b,c], B.drop 3 bs)
where a = bs `index` 0
b = bs `index` 1
c = bs `index` 2
roll :: [Word8] -> Int24
roll = foldr unstep 0
where
unstep b a = a `shiftL` 8 .|. fromIntegral b