c++ - 扫描 JPEG 文件以查找标记

标签 c++ algorithm jpeg file-format

我有一个 C++ 应用程序,它有一个非常简单的要求,即从 JPEG 文件中提取一些元数据。

有各种库可以做到这一点,但最初在制作原型(prototype)时,我只是想快速完成工作,因为我知道 JPEG 文件的结构可以方便地用 a series of markers 描绘出来。 ,(即 {0xFF, 0xXX} 具有相应长度字段的元组),我认为通过从第一个标记开始迭代 JPEG 文件的各个部分并从一个标记迭代到另一个标记直到我击中 End-图像标记。

这很容易实现,只需将 JPEG 数据读入 std::vector<unsigned char> ,然后遍历它,找到标记部分。我最终将此逻辑抽象为一个“标记迭代器”类,使其更易于使用。

通常这很好用。事实上,通常我感兴趣的元数据出现在 SOI 标记之后的第一个标记中(即 APP0 标记,以 { 0xF0, 0xE0 } 开头)。因此,在大多数情况下,我什至不需要实际编写逻辑来遍历整个 JPEG 文件 - 我只需检查始终包含 APP0 标记的 header 即可。

直到那时我才发现我的假设是错误的。显然,0xF0 , 0xE0记号笔 doesn't ALWAYS have to be the first segment .

好的,没问题 - 遍历所有标记无论如何都很容易。除了,然后我遇到了另一个问题。在大多数情况下,找到下一个标记就像将长度字段添加到 JPEG 数据缓冲区中的当前索引位置一样简单。但显然某些长度字段实际上并不指示特定段的整个长度。例如,JPEG 文件中的"Start-Of-Scan" 段后跟"entropy-coded data"。 . “熵编码数据”的大小不包含在长度字段中。

所以...如果您在遍历 JPEG 文件时点击了“扫描开始”标记,您如何知道下一个标记从哪里开始?您是否只需要逐字节进行线性搜索来查找下一个 0xFF特点?

实际上,这也行不通,因为熵编码数据本身可能包含0xFF人物。然而,显然 JPEG 标准要求任何 0xFF出现在熵编码数据中的字节必须后跟 0x00。字节以将其与实际标记区分开来。

好吧,这仍然无法让我在“开始扫描”部分进行强力线性搜索的情况下找到下一个标记。这是唯一可能的方法吗(没有特定于“扫描开始”部分的复杂解析逻辑?)

最佳答案

So ... if you hit a "Start-Of-Scan" marker while iterating over a JPEG file, how do you know where the next marker begins? Do you simply have to do a linear search, byte-by-byte, to find the next 0xFF character?

在扫描中,您可以使用 FF00 或重新启动标记。任何其他 FFxx 序列应该是下一个 block 的开始。

此外,JPEG 图像不必具有 APP0 标记。

关于c++ - 扫描 JPEG 文件以查找标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32873541/

相关文章:

iOS 7 产生随机错误 : JPEG Not a JPEG file: starts with 0x00 0x00

python - 如何使用 opencv python 将图像的 alpha channel 转换为白色?

sql-server - 使用 TSQL 旋转 JPEG 图像,可能吗?

c++ - 如何使用未解析的引用符号显示函数名称

c++ - 如何从 lex/yacc 获取更多解析错误信息?

algorithm - 网格前 10 个值的坐标

java - 在快速排序算法中寻找聪明的主元

c++ - 使用 QServiceManager 未收到信号

c++ - 高效的二进制流

excel - 如何为我的数据集确定最佳数据结构/实现?