compressionjpegdctzigzag

Jpeg Compression fundamentals


I was reading Jpeg compression but I have some problem understanding the basics ! pls see this schema

http://www.cs.cf.ac.uk/Dave/Multimedia/Topic5.fig_29.gif

My problem is in the last steps,consider we have a 16*16 pixel gray image ,so we have 4 blocks of size 8*8. in the zigzag scan we have 4 arrays of size 1*64 which the first index of each array is the DC value and the remaining 63 values are AC components. let's assume the are like;

BLOCK-1::150,-1, 6, 0,-3,....
BLOCK-2:-38, 4,-6,-1, 1,....
BLOCK-3:18,-2,3,4,1,....
BLOCK-4:45,3,5,-1,1,....

I know the DPCM encode the difference from previous 8*8 blocks but how ?! somthing like this :

150,150-(-38),-38-18,45-18>>
150,188,-156,27

then according to JPEG coefficient coding table we have

10010110-111110,10111100-111110,01100011-111110,11011-110

and for the AC component of, (for example), the first row (-1, 6, 0,-3,....)we use RLE so we have:

(0,-1),(0,6),(1,-3),...

then according to JPEG default AC code table we have :

00-0,100-110,111001-10

and if my calculations are correct what happens next ?! we put the first DC of the first block and after that the RLE of 63 remaining values and so on ? I mean for the first block we have 10010110-111110 ,00-0,100-110,111001-10, ...

I'm a bit confused and I couldn't find the answer anywhere :(


Solution

  • First of all I greatly recommend you to refer to jpec a tiny JPEG encoder written in C (grayscale only, baseline DCT-based JPEG, 8x8 blocks only).

    You can find the main compression steps here. In particular, please refer to this line that corresponds to the entropy coding step of the current block.

    the DPCM encode the difference from previous 8*8 blocks but how?

    The entropy coding operates block after block. Assuming the current block is not empty, the DC coefficient encoding is done by first computing the difference between the current and previous DC values:

    int val, bits, nbits;
    /* DC coefficient encoding */
    if (block->len > 0) {
      val = block->zz[0] - s->dc;
      s->dc = block->zz[0];
    }
    

    Note: s represent the entropy coder state. Also, for the first block, s->dc is initialized to 0.

    So val represents the current DC difference:

    1. the size of this difference (= number of bits) is encoded by reading the corresponding DC code in the Huffman table,
    2. then, its amplitude (= value) is encoded.

    If the difference is negative, two's complement is used.

    bits = val;
    if (val < 0) {
      val = -val;
      bits = ~val;
    }
    JPEC_HUFF_NBITS(nbits, val);  
    jpec_huff_write_bits(s, jpec_dc_code[nbits], jpec_dc_len[nbits]); /* (1) */
    if (nbits) jpec_huff_write_bits(s, (unsigned int) bits, nbits);   /* (2) */
    

    For the full version please refer to this code section.