Hamed's JPEG Library

 

My JPEG Image Compression Library

Quick Download:

The Library(18 KB) - Written in C++. To use, include file "jpeg.h", and compile and link all source files into your program. The interface should be clear enough if you look at "jpeg.h". You make an object of type Picture. If you want to open a JPEG file, use the "open" method. Note that "open" will automatically allocate the pixels for you. If you want to create a new JPEG file, first allocate the pixels, using the "setsize" method. After you set your pixels to whatever you want, save the image as a JPEG file using the "save" method. Enjoy.
(Update: Problem with default parameters in jpeg.cc has been fixed -- 7/21/2003)

A C++ Example - An example that shows how to use the library. It is a program that takes two command-line parameters, a JPEG file and a scaling factor, and scales the JPEG file by the scaling factor, writing the output to "scaled.jpg".

A JPEG to Array Converter - A program which, using the above library, opens a JPEG file and creates an array with the RGB values in the image. The output (written to stdout) can then be saved as a header and "#include"d in a C/C++ program.

What is JPEG?
JPEG, an acronym for the Joint Photographics Expert Group (www.jpeg.org) is a compression standard, usually used for images. Contrary to popular belief, JPEG is not an image file format. Technically, JPEG does not specify a file format to use for images. There is, however a specification called JFIF (JPEG File Interchange Format), and most files that we call "JPEG files", should actually be called JPEG JFIF files. Another specification is SPIFF, which is newer than JFIF and as of 2003, not very common yet.

JPEG is a lossy image compression method. That means that when you compress an image using JPEG, and then decompress it, you end up with an image that is slightly different from the original. The smaller you make the JPEG file, the more this lossiness will be. However, the lossiness is not as bad as one might think. For photographs, you can usually achieve a compression ratio of 1:10 to 1:20 without noticeable loss! For more such information, see the JPEG FAQ at http://www.faqs.org/faqs/jpeg-faq.

The JPEG Image Compression Algorithm
I do not intend to explain any algorithms in detail here; there are plenty of sources where such information may be found. In short, however, JPEG works like this.

The RGB image is first translated to YUV, in which every pixel is represented by Y, its luminance, and U and V, the chrominance (color information). Now our image has three components. If the image was a greyscale image, we can throw away the U and V components. For color images, the U and V components are often scaled down to half their size, to reduce the image size. This does not destroy the image quality as one would suspect, since so much of the actual image is in the luminance, while chrominance plays a smaller role.

Each component is then divided into chunks of 8x8 pixels. (The image is expanded as necessary if its width/height is not a multiple of 8.) A discrete cosine transform (DCT) is applied to each 8x8 square. The resulting values are quantized, meaning that they are divided by the values in a quantization matrix, and rounded to the nearest integer. Quantization results in smaller values, and more values that are equal to zero. (The DCT itself makes a lot of the values equal to or near zero; quantization exploits this to increase the number of zero's). Quantization is the "lossy" step in JPEG compression. The larger the values in the quantization matrix, the smaller the compressed image will be. However, larger values in the quantization matrix reduce the compressed image quality.

After that, the 64 values are read in zig-zag order, and compressed first using run-length encoding, and then with Huffman coding. The large number of zero's makes run-length encoding work very well. The resulting data is written to file. Of course, for color images, the different components are usually written to file interleaved, which means that a certain number of blocks from the first component are written, followed by a certain number of blocks from the second component, and so on. For more information about interleaving, see the references.

Decompression works in the same manner, except of course, backwards.

Simple, huh? Try implementing it.

Implementation Tips
It wasn't quite as easy to write as I first thought. First of all, about the only thing you have as a complete reference is the ISO standard (ISO International Standard 10918-1, published separately (but identically) as ITU-T81; see references below). The ISO standard is good, but a little overwhelming at 186 pages. And its only the first part! But the truth is, you only need this first part. And I only read about half of it. Most of the other stuff, like hierarchical mode of operation and lossless encoding, is very rarely seen, and usually isn't implemented. I didn't implement it.

Of course, I don't recommend that you start by reading the standard. There are many sites that give general information about how JPEG works, and you should start by reading these.

You should also read the JFIF file specification. You might decide to implement SPIFF, but JFIF was good enough for me, as it is the most widely used format. These can be downloaded from www.jpeg.org, or more precisely, http://www.jpeg.org/public/jpeglinks.html.

Don't implement the DCT and its inverse (IDCT) as it's written in the standard, and most other places. Four nested "for" loops may work fine, but it makes your program just a little slow. There are better ways to do it.

Implementing JPEG is somewhat complicated. It's not very difficult, but there are so many little things you have to watch out for, and it's so easy to make a mistake. For example, the quantization tables are written in the JPEG file in zig-zag order. At first, I had been reading them in normal row order, and it took me hours to figure out what I was doing wrong. So if you are writing your own library, read the specifications carefully, and be persistent.

References
I hope you find these as useful as I did. Make sure you read several of the pages called "JPEG Introduction", "JPEG Tutor", etc.

Return to main page


Please send all comments, suggestions, questions, etc. to me at comphamed@eml.cc
Last updated Sunday, October 19, 2003