Search code examples
imageencodingbitmapjpeg

JPEG encoding store encoded data


I'm implementing the JPEG encoding and writing it in a JFIF container.

The original image (bitmap):

original bitmap (bmp)

My encoded JPEG:

enter image description here

encoded JPEG with The Gimp (quality 50 and basic settings):

enter image description here

I'm trying to figure out the problem and my guess is it is in the encoded data itself and not in the JFIF header.

The steps (basic overview) that I've done in the encoding:

  1. RGB to YCbCr
  2. Split each Y, Cb and Cr information in MCU's (8x8 blocks). I did not do any subsampling on the Cb and Cr parts as I have not studied yet how this exactly works. (blocks = MCU's)
  3. Apply DCT to all blocks of Y, Cb and Cr
  4. Quantization for all blocks of Y, Cb and Cr
  5. Vectorize (1x64 array) all blocks of Y, Cb and Cr (Zig-Zag)
  6. Apply DPCM (DC) and RLE (AC) on all blocks of Y, Cb and Cr.
  7. Do Huffman magic and save data.

For the last step (7) I process the Y, Cb and Cr blocks as follow:

  1. Process 8x8 Block 1 of Y
  2. Process 8x8 Block 1 of Cb
  3. Process 8x8 Block 1 of Cr
  4. Process 8x8 Block 2 of Y
  5. Process 8x8 Block 2 of Cb
  6. Process 8x8 Block 2 of Cr
  7. Process 8x8 Block 3 of Y
  8. ...

So my data is currently stored as Y Cb Cr Y Cb Cr Y Cb Cr Y Cb ... Is this correct?

or should data of Y, Cb and Cr be processed as following:

Y Y Y Y ... Yn  Cb Cb Cb .... Cbn  Cr Cr Cr Cr .... Crn

My question (as I guess the mistake is in the encoding of the data):

How do you store the encoded data itself?

Trying to figure out why my JPEG encoded output is bigger and not showing correctly. Any help is welcome.


Solution

  • I had a similar issue when I wrote a JPEG encoder from scratch in C. So I use bmptoppm to convert BMP to JPG and use this JPG image as a reference. Open the reference image and the incorrect resultant one (append .hex to the file name, e.g. reference.jpg.hex and myImage.jpg.hex) in your text editor (I use Sublime Text). Firstly, make sure the headers of two JPG files are the same. Then navigate to the encoded data. Find out where the difference is and from which 8 X 8 pixel block the difference derives. Now look into the block and find out which encoding step is incorrect.

    My problem was that there was a wrong value in the Huffman table. So when I first tried to encode the image on the left, I got the one on the right. My encoder is only for gray-scale, so I am not sure about the sequence of Y, Cb and Cr.

    Hopefully, you can fix the error by following the steps.