Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jpeg restart markers

I made jpeg decoder, but I didn't implement restart markers logic. That is reason why my program don't work on some images (for example images saved with Photoshop: File->Save As->jpeg). I want to implement restart marker logic, but there is no detailed online explanation how restart marker logic works. Please can anyone tell me more about restart markers, or suggest me online resource where I can read more about it. Thx!

like image 470
MrD Avatar asked Jan 05 '12 19:01

MrD


1 Answers

Restart markers are quite simple. They were designed to allow resynchronization after an error. Since most JPEG images are transmitted over error-free channels, they're rarely needed. A restart interval is defined with the FFDD marker as a 2-byte number. This tells how many MCUs between restart markers. When you encounter a restart marker (FFD0-FFD7), reset the DC values (Y,Cr,Cb) to 0 and the bitstream is started on a byte boundary (after the FFDx). It's simply a matter of counting through the restart interval over and over as you decode the image. The restart marker values will increment from FFD0 to FFD7 and then start again at FFD0. The marker value itself is not terribly important, but it can indicate if large chunks of data is missing. Here's an example of how I do it in my decoder. I throw away the restart markers in my bitstream reader.

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

Update: Restart markers now serve a new purpose - to allow multi-threaded JPEG encoders and decoders. Since each "strip" of MCUs has its DC values reset at the beginning of each restart interval and starts on a byte boundary, each restart interval can be independently encoded or decoded by a different thread. An encoder can now arbitrarily divide the task into N threads and then 'glue' the data together with restart markers. For decoders, it's not as easy. If restart markers are present, then each interval can be assigned to a different thread. If not present, you can still do some pre-decoding tricks to split the job into multiple threads.

like image 102
BitBank Avatar answered Nov 07 '22 21:11

BitBank