Small JPEG Decoder Library
June 27, 2000 v0.91
Copyright (C) 1994-2000 Rich Geldreich

web: http://www.voicenet.com/~richgel
email: richgel@voicenet.com

--- Introduction

This C++ library decodes JPEG images.  It's not the fastest or most
full-featured JPEG library available, but it's completely free (LGPL
license), uses little memory, and should be relatively easy to
understand and further optimize (mostly because it's so small:  main
decoder module is less than 2300 lines).  It supports the very common
and popular Huffman DCT-based sequential and progressive modes of
operation (8-bit precision only).

If you want an extremely fast JPEG library, you might want to try
Intel's JPEG Library (no source):

http://developer.intel.com/vtune/PERFLIBST/ijl/index.htm

If you just want a full-featured, well tested JPEG library that also
handles compression too, check out the Independent JPEG Group's library
(with source):

http://www.ijg.org

For apps that must read the widest possible array of input types and
require the best decoding quality, I recommend the IJG library.  If your
app's input set is limited in some way (say, you're making a game or
some other app that has prepared resources), and don't mind living on
the edge a bit, this library may suite your needs.

This library may also prove useful to those that want to read JPEG
images on very small 32-bit platforms or embedded devices.

--- Features

Simple (very little code)
Free (LGPL license)
Some MMX optimizations (more to follow), can optionally be disabled
JFIF header parsing
Supports the most common (widely used) file types:
    Greyscale
    YCbCr colorspace: H1V1, H1V2, H2V1, or H2V2 sampling factors
Progressive images

--- Warning

Consider this release of "alpha" or "beta" quality.

This code was ported from an older 16-bit C/ASM implementation.  The
16-bit version has proven to be very reliable and solid in over five
years of service.  Unfortunately, about 30%-50% of the code had to be
rewritten for the port, so I hope no bugs where introduced.  I am
especially concerned about the input stream portions-- I had to rewrite
much of this code to make it more general.  (The original implementation
always assumed the input data was being read directly from disk using a
"greedy" disk buffering algorithm.)

This code still needs to be exaustively tested for memory leaks.
Everything should be freed properly, but you never know.

I have tested this particular implemention with about 175 megabytes of
JPEG images from a variety of sources.

--- History

Many years ago, a friend and I (Matt Pritchard, now with Ensemble
Studios) wrote a 16-bit real mode DOS image viewer named "PowerView"
(PV).  Matt finally convinced me to add JPEG support -- no small feat,
especially considering that at the time (1994) JPEG was still rather new.

The Independent JPEG Group's (www.ijg.org) library was definitely an
option, but its sheer bulk seemed like it would have broken PV.  (PV's
memory situation was rather bleak:  less than ~500k for all code/near
and far data.  It supported EMS/XMS, but only for special cases.  Things
got so bad that I had to use Borland's run-time code swapping/paging
system to free up low RAM.  Modifying the IJG code to handle this
reliably seemed like much more trouble than it was worth.)  Also,
incorporating so much of someone else's code was sure to make the
program less reliable, overall.  We also wanted to stand out from the
crowd, so I decided to create our own implementation.

Approximately one week later, the baseline decoder was working.  The
upsampling/colorspace conversion code, Huffman decoder, and IDCT modules
where written entirely in real-mode assembler.  The IDCT module
performed no multiplies, just lots of overlapped/pipelined, 32-bit adds
from EMS memory lookup tables.  (Each 32-bit add summed two individual
16-bit quantities.)  It also employed an interesting "fast path"
optimization:  using macros, an individual IDCT was created for each
possible input case because many AC coefficients are 0 after
quantization.  (I will probably port this IDCT to 32-bit code and
release it soon.  It performs a lot of table lookups to a 64k buffer, so
I wonder how well it will perform on today's machines.)

One week is not a true estimate of the amount of time it took, of
course.  I studied Pennebaker and Mitchell's "JPEG, Still Image Data
Compression Standard" book and some of the IJG code for several months
before I wrote a single line of code.

Much later on (after the web became very popular) I added support for
progressive images.

A short time after, I wrote a rather complete JPEG encoder from scratch.
This code should be much easier to port because I wrote it keeping
portability in mind.  I'm probably going to release this code within the
next few months.

I also have a PNG encoder/decoder codec which was written 100% from
scratch that I'm going to release under the LGPL too.  This includes the
ZIP codec, which was also written from scratch for other products.

--- Instructions

Make sure you have Visual C++ 6.0 Service Pack 3.  If you want to
compile the assembler code (Intel's _hopefully_ free IDCT module,
mmxidct.asm), you'll need MASM 6.14.  (I've included mmxidct.obj in case
you don't have this product on hand.)

Load the workspace at jpgd/jpgd.dsw.  The example console mode program,
jpg2tga, requires two parameters for it to do anything:  a source
filename (a valid JPEG image), and a destination filename (TGA).
Example:

jpg2tga input.jpg output.tga

The image input.jpg will be written to ouput.tga.  You may then view
output.tga in the viewer of your choice to verify that everything worked
as expected.

Notes:  I hardcoded the "use_mmx" parameter to true in the jpeg_decoder
constructor call..  If you don't have an MMX capable processor you will
need to change this code.  (A production program should check if the
processor supports MMX at run-time and adjust this parameter
accordingly.)

You should be able to compile and link using VC++ 5.0 if you remake the
projects/workspace.  I haven't tried this, though.

--- Intel C/C++ Compiler Notes:

To use the Intel C/C++ Compiler v4.0:  Make sure the "Intel C/C++
Compiler" checkbox is checked in the "Select Compiler" tool.  If it's
not, the h2v2.cpp module will not include the MMX implementation.

The h2v2.cpp module in the included libs was compiled with the Intel
Compiler-- I hope this causes no trouble for those that don't have this
product.  If it does, just recompile.

--- Known Problems

The MMX IDCT seems to have some overflow (?) issues.  They sometimes
appear when decoding images with yellow pixels, which appear purple!
When the use_mmx flag is set to false the problem disappears.

I'm working on a solution.  It'll probably involve completely ditching
Intel's MMX IDCT module for something more reliable.  :-)

--- Future Changes

Partial list:

I hope to verify that the Intel MMX IDCT module is free to include in
this library. If not, I will replace it with something else.

I would like to replace the IJG's integer IDCT module (named IDCT.CPP in
this lib) with something else, because it's copyrighted by Thomas G.
Lane of the IJG.  I am not sure if including this small bit of code
requires the user to include the usual "Parts of this code where written
by the IJG...", etc. statement in their product documentation or "About"
dialog.

Add more MMX/assembler optimizations.  Possibly add AMD 3D-Now or P3
specific modules.

Add bilinear filtering to the upsampler/colorspace conversion code.
Right now, only a simple box filter is available.  This can lead to some
pretty nasty looking artifacts with certain image types.  (I dread doing
this because it will be a bit complicated to add!)

--- License

Except for those modules which are copyrighted by others, this library
is covered under the LGPL license.  Please see license.txt.

There are two modules included in this library which I did not write.  I
mainly included these modules because I was short on time:

mmxidct.asm is from Intel.  I am actually unsure of its license at this
time.  The text _seems_ to indicate that it's not copyrighted by Intel,
but I am not 100% sure. Please see the top of this file for more information.

idct.cpp is from the IJG.  It's copyrighted by Thomas G. Lane.  Please
see the top of this file for more information.

