首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用attoparsec解析JPEG标记

使用attoparsec解析JPEG标记
EN

Stack Overflow用户
提问于 2011-01-06 12:14:06
回答 2查看 609关注 0票数 3

作为一个促进我对Haskell的了解和适应的项目,我正在努力实现一个JPEG解码器,它将在未来的计算机视觉工作中派上用场。

我选择的第一步是解析图像中的所有“标记”。这些值由字节0xFF后跟非0字节表示。后跟0x00字节的0xFF字节应视为正常数据。

我遇到的问题是,在遇到0xFF 0x00组合时,解析似乎完全完成,并且找不到更多有效的标记(如果您在标准JPEG上运行,您将看到图像标记的开始被解析,但不会看到图像标记的结束,因为在图像数据本身中经常出现0xFF 0x00 )。

代码语言:javascript
复制
import System.Environment
import System.IO

import Control.Applicative hiding (many)
import Data.Attoparsec as A
import qualified Data.ByteString as BS

parseMarker = do
  part1 <- word8 0xFF
  part2 <- notWord8 0x0
  return (part1, part2)

parseSection = do
  A.skipWhile (\x -> x /= 0xFF) *> parseMarker

parseBody = do
  many parseSection

parseJPEG jpeg = do
  handleParseResult $ feed (parse parseBody jpeg) BS.empty

handleParseResult result = do
  case result of
    Fail _ _ msg -> msg
    Done _ r -> show r
    _ -> ""

main = do
  (filename : _ ) <- getArgs
  handle <- openFile filename ReadMode
  contents <- BS.hGetContents handle
  putStrLn $ parseJPEG contents
  hClose handle

https://gist.github.com/767488

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-01-06 13:00:01

由于parseMarker使用输入,但可能在中途失败,因此当遇到0xFF 0x00时,您必须能够“倒带”并重试不同的解析。

我没有安装Attoparsec,但我假设它类似于Parsec,它在默认情况下不会回溯。

代码语言:javascript
复制
parseSection =
    skipMany (notWord8 0xFF <|> try (word8 0xFF >> word8 0x0)) >> parseMarker
票数 2
EN

Stack Overflow用户

发布于 2011-01-06 13:08:31

问题是你没有告诉它去解析一个0xFF,0x00的序列,所以已经很晚了,所以希望下一个回答者会给出答案(也许它对你的帮助已经足够了),但是这里有一个替代的parseMarker和附带的handleParseResult

代码语言:javascript
复制
parseMarker = do   -- or call it "parsePotentialMarker"
  part1 <- word8 0xFF
  part2 <- anyWord8
  return $
    if (part2 /= 0)
        then [(part1, part2)]
        else []

-- ... skipping other functions...
handleParseResult result = do
  case result of
    Fail _ _ msg -> msg
    Done _ r -> show (concat r)
-- ...

顺便说一句,在问题中,在代码中有一个完整的功能测试会稍微有帮助,比如:

代码语言:javascript
复制
main =
  let contents = BS.pack [1,2,3,4,0xFF,1 {- marker 1 -},0xFF,0x00,0xFF,2 {- marker 2 -},31,13,0xFF,0x00]
  in putStrLn $ parseJPEG contents
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4611680

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档