Haskellに関する知識と快適さをさらに高めるプロジェクトとして、将来のコンピュータービジョン作業に役立つJPEGデコーダーの実装に取り組んでいます。
私が選択した最初のステップは、画像内のすべての「マーカー」を解析することです。これらは、バイト0xFFとそれに続く非0バイトで示されます。0xFFバイトの後に0x00バイトが続く場合は、通常のデータとして扱われます。
私が遭遇している問題は、0xFF 0x00の組み合わせに遭遇すると、解析が完全に終了し、有効なマーカーが見つからないように見えることです(標準のJPEGで実行すると、画像マーカーの開始は解析されますが、終了は表示されません)多くの場合、0xFF 0x00の画像マーカーは画像データ自体の中で発生します)。
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