In this project I attempted to implement basic JPEG compression using only basic Matlab functions. This included going from a basic grayscale bitmap image all the way to a fully encoded file readable by standard image readers. I will show that I have implemented the majority of the project, including much of the final binary coding. Although I never obtained a fully completed image from my functions, I came very close.
In this section I will present the steps of obtaining a finalized JPEG file and how I implemented each step in matlab. I will comment on possible improvements and mistakes made in each case. The code used is attached at the end of this report.
Step1: Converting the base image to 8x8 matrices, DCT transform, quantizing
These steps were relatively easy, especially in matlab, which is specifically set up to work with matrices. The 2-D discrete cosine transform is done simply with the dct2() command. After splitting the matrix into 8x8 matrices and performing the DCT, a simple piecewise division by the quantization matrix obtains the quantized matrices needed for the next step.
Step 2: Zig-Zag Encoding of Quantized Matrices
I found no matlab implementation for this function, so I wrote one myself. I took advantage of the fact that each diagonal row has addresses that add up to the same number. Depending on whether the number is even or odd determined the direction of the iteration through the row. The code I wrote is able to zig-zag through any matrix of equal height and width. This could be useful if one wanted to experiment with deviding images into matrices larger than 8x8.
Step 3: Conversion of quantized vectors into the JPEG defined bitstream
For this step, I started with an old implementation of the default AC code written by Yu Hen Hu. After updating the code to work with Matlab 7 I modified the code to encode the first number in the incoming vector with the default DC code, the table for which I added to the file. The function returns a completed bitstream to correspond to the input of the quantized vector.
I am sorry to say I cannot guarantee that the code contained in vecenc.m is at all reliable. I tested single vectors with standard examples and obtained the correct result. However, having never obtained a final result, I cannot guarantee that this function complies with the JPEG standard.
Step 4: Construction of the JPEG File header, Writing the File
Being relatively inexperienced with coding in general, this step presented me with the most trouble overall. It took several hours to determine how to encode a binary vector into a file. It took even longer to realize that each byte encoded into the file was being represented with the least significant bits on the left side. After overcoming that obstacle, I was faced with the task of constructing a file header for my bit stream.
The JPEG standard only goes as far as conversion to the binary bit stream. While that process is well defined in scientific papers, the construction of a JPEG file header is not. In the matlab file head.m, I tried to express what I learned about the process in the most expressive way possible.
It seems that the JPEG file is broken into many blocks. Each block begins with two bytes, the first being FF in hexadecimal and the second being 'XX' where different 'XX's denoting different blocks. The second part of each block is the length, in bytes, of the block including the two length bytes. The rest of the block contains the data as defined by the block type.
As of this writing, I am in the middle of coding head.m, but will be unable to finish due to time constraints. I am confident, though, that I have a very good understanding of how the rest of the header construction would proceed.
While not completing the goal I set out to achieve, I have demonstrated that conversion from a grayscale image to the JPEG encoded binary bit stream is a fairly simple and straightforward process. It comes as no surprise to me that the file I/O was the most challenging part of the process.
As for where to go from here, I hope to complete the project in my free time and publish the matlab files on the internet. I believe that while there are far more powerful and efficient implementations of the JPEG algorithm out there, other students like myself would benefit from a simple and straightforward implementation that emphasizes step-by step explanations of what is going on and why.