【问题标题】:Generating AC elements from jpeg file从 jpeg 文件生成 AC 元素
【发布时间】:2011-12-19 19:28:32
【问题描述】:

我正在解码 jpeg 文件。我已经生成了霍夫曼表和量化表,并且已经到了必须解码 DC 和 AC 元素的地步。例如,假设我有下一个数据

FFDA 00 0C 03 01 00 02 11 03 11 00 3F 00 F2 A6 2A FD 54 C5 5F FFD9

如果我们忽略 SOS 标记中的几个字节,我的真实数据是从 F2 字节开始的。所以让我们把它写成二进制(从 F2 字节开始):

1111 0010 1010 0110 0010 1010 1111 1101 0101 0100 1100 0101 0101 1111
  F    2    A    6   2     A    F    D    5    4    C    5    5   F

解码时,第一个元素是亮度 DC 元素,所以让我们对其进行解码。

[1111 0]010 1010 0110 0010 1010 1111 1101 0101 0100 1100 0101 0101 1111
  F    2    A    6   2     A    F    D    5    4    C    5    5   F

所以 11110 是元素 08 的霍夫曼代码(在我的例子中)。这意味着接下来的 8 位是我的 DC 值。当我取接下来的 8 位时,值为:

1111 0[010 1010 0]110 0010 1010 1111 1101 0101 0100 1100 0101 0101 1111
  F    2    A    6   2     A    F    D    5    4    C    5    5   F

DC 元素值为 -171。

这是我的问题:接下来是亮度 AC 值,但在 AC 非零的情况下,我不太了解标准?天呐!

【问题讨论】:

  • 我可以推荐一个名为 impulsion Adventure 的网站,它解释了 jpeg 所需的大量解码
  • 我已经访问并分析了推荐页面,但是有解释,例如当AC元素为零时。
  • 您可以从上述站点下载 jpeg snoop 源代码,这应该可以回答您对 jpeg 解码的任何其他问题

标签: jpeg huffman-code


【解决方案1】:

如您所见,DC 值被定义为指定 DC 正值或负值的“额外”位数。 AC 系数的编码方式不同,因为它们中的大多数都是 0。Huffman 表为 AC 系数定义了每个条目,具有“跳过”值和“额外位”长度。跳过值是在存储值之前要跳过多少个 AC 系数,额外的位与 DC 值的处理方式相同。解码 AC 系数时,您解码的值从 1 到 63,但 MCU 结束编码的方式可能会有所不同。您可以将实际值存储在索引 63 处,或者如果您的索引 > 48,则可以获得 ZRL(零运行长度 = 16 个零),或任何可以让您结束的组合。一个简化的解码循环:

void DecodeMCU(signed short *MCU)
{
int index;
unsigned short code, skip, extra;

   MCU[0] = decodeDC();
   index = 1;
   while (index < 64)
   {
      code = decodeAC();
      skip = code >> 4; // skip value
      extra = code & 0xf; // extra bits
      index += skip;
      MCU[index++] = calcACValue(extra);
   }
}

颜色分量可以交错(典型)或存储在单独的扫描中。元素在每个 MCU 中以之字形顺序编码(首先是低频元素)。定义 MCU 的 8x8 系数块的数量取决于颜色二次采样。对于 1:1,将有 1 个 Y,然后是 1 个 Cr 和 1 个 Cb。对于典型的数码相机图像,水平轴是二次采样的,因此您将获得 2 个 Y 块,然后是 1 个 Cr 和 1 个 Cb。压缩图像的质量设置决定了使用的量化表以及编码了多少个零 AC 系数。质量越低,每个 MCU 的零点就越多。当您在 MCU 上执行逆 DCT 时,零的数量将决定在 8x8、16x8、8x16 或 16x16 像素块中保留多少细节。以下是基本步骤:

1) 熵解码8x8系数块,每个颜色分量单独存储
2) 去锯齿形和去量化系数
3) 对系数执行逆 DCT(对于 4:2:0 子采样可能是 6 个 8x8 块)
4) 将颜色空间从 YCrCb 转换为 RGB 或您需要的任何内容

【讨论】:

  • 这对我帮助很大。您说过“颜色分量可以交错(典型)或存储在单独的扫描中”。如何从文件中生成该信息?
  • 在 SOF(帧开始)标头中,它指定颜色分量的数量(对于普通彩色图像,通常为 3)。 SOS(扫描开始)标题告诉您扫描中有多少颜色分量。如果为 3,则颜色是交错的,如果小于,则颜色存储在单独的扫描中。
  • 非常感谢你救了我。
  • 我还有一个问题:如果我有 8x8 图片和您上面提到的色度二次采样 (4:2:2)。因为色度子采样解码过程会是:2 Y 1Cb 1Cr。但是我的图片尺寸是 8x8,我很困惑,因为图片尺寸是 8x8,所以我无法读取第二个 Y 块。
  • 如果图片尺寸小于MCU边界,则忽略多余的像素。例如,如果您的图像是 8x8,但在两个维度上对颜色进行二次采样,则 MCU 将为 16x16,但图像的可见部分将仅是左上角的 8x8 像素块。即使只使用了 8x8 像素,整个 MCU(6 个 8x8 系数块)也需要在文件中编码。
猜你喜欢
  • 1970-01-01
  • 2016-02-19
  • 2011-07-15
  • 2015-10-05
  • 1970-01-01
  • 1970-01-01
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多