Jpeg重启标记

时间:2012-01-05 19:40:55

标签: file jpeg huffman-code decoder

我制作了jpeg解码器,但我没有实现重启标记逻辑。这就是为什么我的程序不能处理某些图像(例如用Photoshop保存的图像:File-> Save As-> jpeg)的原因。我想实现重启标记逻辑,但没有详细的在线解释重启标记逻辑如何工作。请任何人都可以告诉我有关重启标记的更多信息,或者建议我在线资源,我可以在其中详细了解它。 THX!

1 个答案:

答案 0 :(得分:17)

重新启动标记非常简单。它们被设计为允许在发生错误后重新同步。由于大多数JPEG图像是通过无差错通道传输的,因此很少需要它们。使用FFDD标记将重启间隔定义为2字节数。这告诉重启标记之间有多少个MCU。当遇到重启标记(FFD0-FFD7)时,将DC值(Y,Cr,Cb)重置为0,并在字节边界(FFDx之后)上启动比特流。在解码图像时,只需要反复计算重启间隔。重启标记值将从FFD0增加到FFD7,然后再从FFD0开始。标记值本身并不是非常重要,但它可以指示是否缺少大块数据。这是我在解码器中如何做到这一点的一个例子。我丢弃了比特流阅读器中的重启标记。

iRestartCount = iRestartInterval;
for (y=0; y<Height_in_MCUs; y++)
   {
   for (x=0; x<Width_in_MCUs; x++)
       {
       <decode an MCU>
       if (iRestartInterval) // if there is a restart interval defined
          {
          if (--iRestartCount == 0)
             {
             iRestartCount = iRestartInterval; // reset restart inverval counter
             iDCPred0 = iDCPred1 = iDCPred2 = 0; // reset DC predictors
             if (*iBit & 7) // adjust bitstream to start on the next byte boundary
                {
                *iBit += (8 - (*iBit & 7));
                }
             } // if restart interval expired
          } // if restart interval defined
       } // for x
    } // for y

更新:重新开始标记现在有了新的用途 - 允许使用多线程JPEG编码器和解码器。由于MCU的每个“条带”的DC值在每个重启间隔开始时复位并从字节边界开始,因此每个重启间隔可以由不同的线程独立编码或解码。编码器现在可以任意将任务划分为N个线程,然后将数据与重启标记“粘合”在一起。对于解码器来说,它并不容易。如果存在重新启动标记,则可以将每个间隔分配给不同的线程。如果不存在,您仍然可以执行一些预解码技巧,将作业拆分为多个线程。