Hierarchical JPEG Encoding CMPT 820

Summer 2003

Project Introduction

 The purpose of this project was to understand more in detail the three main parts of Hierarchical JPEG. Three parts that I implemented in C++ are: DCT transformation, quantization and hierarchical coding for both the encoder and decoder. I will not discuss details of algorithm since they are fully available at the course website:                                      http://www.cs.sfu.ca/CC/820/li/

 

Software Introduction

 The application is written in C++. I used C++ because of two reasons, first I wanted to make my C++ background stronger and also I thought the software would be faster in C++ than other languages. 

I also implemented the algorithm in Matlab. It was much easier and more fun using Matlab. My suggestion to other students is that if they want to just get the assignment done, then implement it in Java rather than C++. 

 

Download the Software

Download executable file plus required library (zipped 325 Kb)

Download C++ files plus required library (zipped 363 Kb)

Download sample code for using IJL (Intel JPEG Library) (zipped 97 Kb)

How to use this program 

 In order to run the program using executable files, drag a picture and drop it in the file. If you like to recompile the whole program, then you need to specify input image name under Project->Setting->Debug->Program Argument. 

When application is running, there are a number of keys on right hand side. You can specify to see the actual Y, Cr, Cb, I or Q plane of the image. The three extra buttons available on right side of Y, I and Q are the result of either DCT transformation or IDCT (inverse DCT) on given plane.

On the bottom right corner, you can change the quality of HJPEG encoding. In this application, higher quality corresponds to lower quantization value and therefore more information storage. There are two options available for quantization matrices. Values for both of them are read from a data file called: “quantizedMatrix.txt”. The data in the file can be modified to experiment result with different quantizatin factors. I did not have time to make a nice user interface for this part, instead you have to go directly to the files and change the values.

On left side of Quantization options, there is a button that does HJPEG given the level of requested hierarchy. Every time the hierarchy level is changed, HJPEG button should be clicked to apply the changes. You can view the result on the window on top left corner. Below is a sample of tests that I ran for the 3 level of HJPEG. The left image is applying Luminance quantization with 100% quality in second level. Right image is applying same quantization matrix but with quality of 12%:

Quality = 100%, HJPEG level 2 Quality = 12%, HJPEG level 2
Figure 1.  

If you are interested to view DCT transform of each level, you can click on DCT button. Then result of each layer can be viewed by clicking on ‘Y Res’, ‘I Res’ and ‘Q Res’ on top right corner. To view the original image or its original values of layers click on ‘Original Image’, ‘Y Plane’… Figure 2 shows Y plane and DCT transformed for the first layer of HJPEG:

 

Y plane, 1st level DCT transfored of Y plane, 1st level
Figure 2.  

The last scroll bar is zoom functionality. This function is primitive and all it does is up-samples viewing part with no smoothing.

 

Software Design

For  the first 2 weeks Bill Cressman and I were looking for a good library in C++ that can open different image file (TIFF, JPEGH, BMP, PNG…) and returns it in such a good format that can be easily manipulated and stored back in any desired format. Unfortunately none was able to help us including student from past years. Everyone that I knew implemented it in Java sine it is much easier. The sample code that was given in the class was no use. I found a library from Intel JPEG Library v 1.51 (IJL) which was quite good. It let me open images in any format and it returns an array of Bytes and I can work with it and pass it back to write to any file. The problem was that we had to install the library which itself was almost 1 MB. I wrote a small code for practice to read a JPEG file and split it into smaller one and store it back. The C++ code is available to download from this site. However, since Bill and I wanted to work together on the final project we decided to use same library. Bill found a ‘FreeImage’ library which was open source and free unlike Intel library and we decided to use this library. He gave me some basic code that shows how to use the library and I used it to move on. We also looked for a good and small matrix library, but we weren’t successful and we choose one that looked pretty small and easy to understand. We later realized that working with this matrix library was a big disaster, it had many bugs and wasted days of my time. 

Below are the design structure of my software:

mainHJPEG:                                                                                                                                 Self-Creating class that initializes itself and creates the linked-list HJPEG. 

ImgDialog:                                                                                                                                    Holds the GUI part of the application. 

HJPEG:                                                                                                                                       It is a linked list structure that holds all the necessary operations (DCT, IDCT, Quantization, hierarchical encoding/decoding) in it. Each instance in the linked-list corresponds to a level of HJPEG. 

RGBImage:                                                                                                                          Holds necessary information about and image, normally R, G,  B, Y,  I , Q,  Cr and Cb plane. 

Matrix Library:                                                                                                                        An open source library from Somnath Kundu and I do not suggest to use it AT ALL. But it has a good interface and is small. I expanded this library and added some more functionality to it.

 FreeImage Library:                                                                                                                  A very nice and small library. I did not have any problem with it and it seems to be bug free. The library is open source and available at http://sourceforge.net/projects/freeimage.

 

What I learned 

Besides the implementation detail of JPEG encoding, I also did some experiment with smoothing part of the image. I realized that it does not matter how up-sampling and down-sampling the matrices are done, despite my initial expectation. The only  part that is crucial is that these two operations are symmetric, so if method x is used for up-sampling same approach should be used form down-sampling. In my code I have two versions for up-sampling. One does smoothing for missing data and the other one just puts the closest neighbor as its value. Both seem to be working fine, so I chose to work with first one as it is faster in terms of computation. On right side you can see result using both up-sampling:

 

 

 

For DCT and IDCT transformation I implemented two versions. One version works with basis functions. It applies an 8x8 matrix which each of its buckets is a 8x8 matrix itself. I wanted to experiment how my data would be different than the other method. For my second approach, I used the approach given in Matlab help. It gives an 8x8 matrix and to get DCT transform of an image you just apply  dct_transpose*image*dct. The values for the matrix are read from file dctMatrix.txt and values are:            

0.354 0.354 0.354 0.354 0.354 0.354 0.354 0.354
0.49 0.416 0.278 0.098 -0.098 -0.28 -0.42 -0.49
0.462 0.191 -0.19 -0.46 -0.462 -0.19 0.191 0.462
0.416 -0.1 -0.49 -0.28 0.278 0.49 0.098 -0.42
0.354 -0.35 -0.35 0.354 0.354 -0.35 -0.35 0.354
0.278 -0.49 0.098 0.416 -0.416 -0.1 0.49 -0.28
0.191 -0.46 0.462 -0.19 -0.191 0.462 -0.46 0.191
0.098 -0.28 0.416 -0.49 0.49 -0.42 0.278 -0.1

 For inverse DCT (IDCT) opposite of above operation is done: dct*DATA*dct_tarnspose

The other interesting thing that I found was use of DCT. In my opinion result of DCT transform was showing me the edges of the images, especially in Y plane.

 

What could have helped

 I should thank you my friend Bill Cressman for finding this nice FreeImage library. I really think that students should be provided with basic starting libraries. I have written a simple program that uses IJL (Intel JPEG Library), in case any other student decides to use this library. IJL might be a better alternative, since university can have support from INTEL and besides the library comes with nice documentation.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

      

 


Main view of the software

 

 

 

 

Top right corner features
You can see different layers of the image plus the original image by clicking on each button

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Use zoom option
You can zoom into the picture by sliding the zoom option

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

non-smoothed upsampled level 2 of HJPEG

smoothed upsampled level 2 of HJPEG