2

I'm decoding jpeg file. I have generated huffman tables, and quantization tables, and I have reach the point where I have to decode DC and AC elements. For example lets say I have next data

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

If we ignore few bytes from SOS marker, my real data is starting from F2 byte. So lets write it in binary (starting from F2 byte):

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

When decoding, first element is luminance DC element so let's decode it.

[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

So 11110 is Huffman code (in my case) for element 08. This means that next 8 bits are my DC value. When I take next 8 bits the value is:

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 element value is -171.

Here is my problem: next is luminance AC value, but I don't really understand standard in a case when is AC non zero? Tnx!

MrD
  • 2,423
  • 3
  • 33
  • 57
  • 1
    i can recommend a website called impulse adventure that explains a lot of the decoding required for jpeg – Jimmy Dec 20 '11 at 14:55
  • I have already visited and analyzed recommended page, but there is explanation for example when AC elements are zero. – MrD Dec 21 '11 at 01:00
  • you can download jpeg snoop source code from the above site, this should answer any other questions you have about jpeg decoding – Jimmy Dec 21 '11 at 13:28

1 Answers1

4

The DC values, as you've seen, are defined as the number of "extra" bits which specify the positive or negative DC value. The AC coefficients are encoded differently because most of them are 0. The Huffman table defines each entry for AC coefficients with a "skip" value and an "extra bits" length. The skip value is how many AC coefficients to skip before storing the value, and the extra bits are treated the same way as DC values. When decoding AC coefficients, you decode values from 1 to 63, but the way the encoding of the MCU ends can vary. You can have an actual value stored at index 63 or at if you're at index > 48, you could get a ZRL (zero run length = 16 zeros), or any combination which takes you past the end. A simplified decode loop:

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);
   }
}

The color components can be interleaved (typical) or stored in separate scans. The elements are encoded in zigzag order in each MCU (low frequency elements first). The number of 8x8 blocks of coefficients which define an MCU varies depending on the color subsampling. For 1:1, there will be 1 Y followed by 1 Cr and 1 Cb. For typical digital camera images, the horizontal axis is subsampled, so you will get 2 Y blocks followed by 1 Cr and 1 Cb. The quality setting of the compressed image determines the quantization table used and how many zero AC coefficients are encoded. The lower the quality, the more of each MCU will be zeros. When you do the inverse DCT on your MCU, the number of zeros will determine how much detail is preserved in your 8x8, 16x8, 8x16 or 16x16 block of pixels. Here are the basic steps:

1) Entropy decode the 8x8 coefficient blocks, each color component is stored separately
2) De-zigzag and de-quantize the coefficients
3) Perform inverse DCT on the coefficients (might be 6 8x8 blocks for 4:2:0 subsampling)
4) Convert the colorspace from YCrCb to RGB or whatever you need

BitBank
  • 8,500
  • 3
  • 28
  • 46
  • This helped me alot. You said that "The color components can be interleaved (typical) or stored in separate scans". How do I generate that information from file? – MrD Dec 23 '11 at 16:33
  • 1
    In the SOF (start of frame) header, it specifies the number of color components (usually 3 for normal color images). The SOS (start of scan) header tells you how many color components are in the scan. If it's 3, then the colors are interleaved, if it's less, then the colors are stored in individual scans. – BitBank Dec 23 '11 at 17:32
  • I have another question: If I have 8x8 picture, and chroma subsampling as you mentioned above (4:2:2). Because of chroma subsampling decoding process would be: 2 Y 1Cb 1Cr. But my picture dimensions are 8x8, and I'm confused, I can not read second Y block because picture dimensions are 8x8. – MrD Dec 23 '11 at 22:24
  • If the picture dimensions are smaller than the MCU boundary, then the extra pixels are ignored. For example, if your image is 8x8, but subsamples the colors in both dimensions, the MCU will be 16x16, but the visible part of the image will be only the upper left 8x8 block of pixels. Even though only 8x8 pixels are used, the entire MCU (6 8x8 blocks of coefficients) need to be coded in the file. – BitBank Dec 23 '11 at 22:49