解析JPEG SOS标记

ap0*_*ap0 11 jpeg file-format

有一个问题具有相同的标题但不幸的是它对我没有帮助.

我正在尝试解析SOS标记的数据.我能找到的所有文档都说在marker(0xFFDA)之后是一个两个字节的数字,它定义了这个段的长度 - 例如这里 - 和大多数可变大小的标记一样.但在这种情况下,我似乎无法正确理解它.它适用于所有其他标记类型.

我检查了多个文件,但是无法做到这一点.这个数字是不是定义了完整的SOS字段有多长?因此对于基线JPEG,应该有一个SOS片段,在此之后应该跟随End of Image标记.如果它是渐进的,则可以存在多个SOS段,但仍然应该具有长度字段.

我有一张带SOF0标记的照片所以它应该是基线.我相信这是正确的SOFn标记,因为可以在该标记之后找到图像分辨率.使用十六进制编辑器,我找到了3个0xFFDA标记,所有标记都0x000C在以下2个字节中.因此,据我所知,该段应始终为12字节长.但是在所有3种情况下,在12字节数据之后没有新标记.我想最后一个是我正在寻找的扫描,因为如果值0xFF出现,则接着是0x00- 除了重置标记.

那两个字节0xFFDA不是长度字段吗?

编辑: 所以,由于评论和答案,似乎没有实际压缩数据的长度字段,只有知道它结束的方式似乎是解码它.

为什么Baseline DCT图像有多次扫描?我明白为什么它有两个; 主图像和缩略图,但第三次扫描是什么?

但还有一件事.根据DRI标记(定义重启间隔),它包含扫描应具有重启标记的值0xFFD0 - 0xFFD7.但我似乎错过了解或者说我做得不对.例如,标记包含0x0140重新启动间隔的值.在下面的扫描中,我从头开始搜索第一个,0xFFD0但它是在862个字节而不是320个之后.

use*_*003 5

SOS 标记包含压缩数据;JPEG 流中最复杂的部分。SOFn 标记指示数据的格式。SOF0 和 SOF1 的处理方式相同。SOF2(渐进式)有点不同。(SOFn 标记的读取不常用或不普遍支持)。

长度是 SOS 标头的长度,而不是压缩数据的长度。大多数标头仅适用于逐行扫描 (SOF2)。

压缩数据跟在标题后面。压缩数据没有长度。您必须扫描数据才能找到下一个标记。

  • 您不必解码数据即可找到 SOF 标记的结尾。扫描流中的 FF。FFFF 表示压缩的 FF 值(跳过那些)。FFD0 - FFD7 是重启标记。忽略那些。任何其他 FFxx 值都应该是流中的下一个块。除非您解压缩,否则重新启动标记没有任何意义。它们是 MCU 间隔,而不是字节间隔。 (4认同)
  • 我有一个错误。FF 编码为 FF00。除了重新启动标记之外,这就是您需要检查的全部内容。 (4认同)
  • @MartinKersten,我相信 user3344003 是对的。来自维基百科[页面](https://en.wikipedia.org/wiki/JPEG):*在熵编码数据中,在任何 0xFF 字节之后,编码器在下一个字节之前插入一个 0x00 字节,以便有似乎不是一个没有意图的标记,防止帧错误。解码器必须跳过这个 0x00 字节。这种技术称为字节填充(参见 JPEG 规范部分 F.1.2.3)* (3认同)

fid*_*der 5

如何在 SOS 标记(0xFFDA)之后找到下一个标记的摘要

  1. 跳过 SOS 标记后的前 3 个字节(2 个字节标头大小 + 1 个字节扫描中的图像分量数)。
  2. 搜索下一个FFxx标记(跳过每个标记FF00,范围从FFD0FFD7,因为它们是扫描的一部分)。

*这是 user3344003 帖子下面的评论摘要 + 我的知识 + 来自https://www.w3.org/Graphics/JPEG/itu-t81.pdf的表 B.1 。

*根据表 B.1,我还可以怀疑第 2 点中也应该跳过 valueFF01FF02through FFBF,但我不确定它们是否不能作为编码的 SOS 数据的一部分出现。


上面的附加问题:

为什么基线 DCT 图像有多次扫描?我会理解为什么它有两个;主图像和缩略图,但第三次扫描是什么?

如果图像流包含 APP2 标记(0xFFE2),这告诉我们它可以(但不是必须)多图片 JPEG(标记名为 MPF),我们可以有超过 3 个图像。一般来说APP标记可以存储任何东西,有很多与JPEG文件中的APP段相关的标准。

第一个表告诉我们每个 APP 段中可以存储的“事物”:
https://exiftool.org/TagNames/JPEG.html