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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With