如何有效地解析熵编码的JPEG块?

时间:2016-02-26 07:50:12

标签: parsing haskell jpeg attoparsec

我只是试图跳过.JPEG文件中的SOS_MT块,我不想将数据用于任何事情,我只是想知道它的结束位置。根据我从JPEG's article in Wikipedia的理解,虽然JPEG文件中的所有其他块都以指示块长度的几个字节开头,但是SOS_MT块是......好吧,你有一个邪恶的沼泽没有选择,只能逐字节解析,直到你到达它结束。

所以我带了以下代码来做到这一点:

entropyCoded :: Parser Int
entropyCoded = do
    list_of_lengths <-  many' $
         (
           do
             _ <- notWord8 0xFF
             return 1
         )
         <|>
         (
           do
             _ <- word8 0xFF
             _ <- word8 0
             return 2
         )
         <|>
         (
           do
             l <- many1 (word8 0xFF)
             _ <- satisfy (\x -> ( x >= 0xD0 && x < 0xD7 ))
             return $ 1 + length l
         )
         <|>
         (
           do
             _ <- word8 0xFF
             maybe_ff <- peekWord8'
             if maybe_ff == 0xFF
               then
                 return 1
               else
                 fail "notthere"
         )
    foldM (\ nn n -> nn `seq` return (nn + n) ) 0 list_of_lengths

此代码使用Atoparsec,并且据我有机会验证它,它是正确的。这很慢。关于如何改进,性能方面的解析器的任何提示?

2 个答案:

答案 0 :(得分:3)

如果您想跳过SOS市场,只需寻找下一个不是重启标记的标记。

读取字节,直到找到和FF。如果下一个值为00,则它是压缩的FF值并跳过它。如果是重启标记,则跳过它。否则,FF应该开始下一个块。

答案 1 :(得分:1)

根据ISO/IEC 10918-1 : 1993(E)标准,对先前的答案进行了少量补充:

  

B.1.1.5熵编码的数据段

     

一个熵编码的数据段包含一个熵编码过程的输出。无论使用的熵编码过程是霍夫曼还是算术运算,它都由整数字节组成。

     

注意1

     

使熵编码的段成为整数字节的过程如下:对于霍夫曼编码,如果需要,使用1位填充填充压缩数据的末尾以完成段的最后字节。对于算术编码,字节对齐   按照终止熵编码段的过程执行(请参阅D.1.8)。

     

注意2

     

为了确保标记不会在熵编码的段内出现,由霍夫曼或算术编码器生成的任何X'FF'字节,或由填充1生成的X'FF'字节遵循以上注释1中所述的位   通过一个“填充的”零字节(请参阅D.1.6和F.1.2.3)。

因此,当您在位置 N 的熵编码部分中输入 0xFF 时,再向前读取一个字节。如果下一个字节为 0x00 ,则为“填充”零。如果是另一个 0xFF ,则存在填充,请从 N + 1 重新检查。每隔一个字节( 0x01-0xFE )都是下一个标记的一部分。