1

我只是想跳过 .JPEG 文件中的 SOS_MT 块,我不想将数据用于任何事情,我只想知道它在哪里结束。根据我从 Wikipedia 中 JPEG 的文章中了解到的内容,虽然 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,据我有机会验证它是正确的。只是很慢。关于如何在性能方面改进此解析器的任何提示?

4

2 回答 2

3

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

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

于 2016-02-26T20:34:13.707 回答
1

根据ISO/IEC 10918-1 : 1993(E)标准,对上一个答案的一个小补充:

B.1.1.5 熵编码数据段

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

注1

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

笔记2

为了确保标记不会出现在熵编码段中,由 Huffman 或算术编码器生成的任何 X'FF' 字节,或由所描述的 1 位填充生成的 X'FF' 字节在上面的注 1 中,后跟一个“填充的”零字节(见 D.1.6 和 F.1.2.3)。

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

于 2018-11-17T05:10:24.297 回答