				GIFLib

------ Concepts & Caveats --------------------------------------------------

I created the GIFLib classes while developing a 3DS file viewer.  Some 3DS
files store texture information in GIF files.  My original concept was to
simply read the color table and the bit information from the file and
reformat it as required by OpenGL; however, I went ahead and added some
display and animation capability for my amusement (as well as debugging ;-)).
I thought it might be useful to myself and to others in the future.

GIF files are the only format that I have seen that can store multiple images
per file for animation purposes.  It was simpler for me to write a GIF reader
in C++ than in C. My BMGLib DLL (which reads and writes TIFFs, JPEGs, and
PNGs) assumes that each file contains a single image.  Furthermore, those
functions are written in C.  For these reasons, the GIFLib code is kept
separate from the BMGLib project.

The GIFLib classes encapsulate most of the capabilities of a GIF image.
It will display and render static and animated GIFs.  It "almost" conforms
to the GIF89a standard.  It will read and display GIF89a images; however,
it will not display plain text extensions.  The GIFLib classes will read files 
that contain plain text extensions, but it will not display the text.  I was 
not concerned about displaying text and intentionally left this feature out.

The GIFLib classes will not save an image to a GIF file.  GIF images use
LZW compression to reduce the size of a file.  UNISYS currently owns the patent 
to LZW compression and charges an excessive fee to any one that uses it.  I 
intentionally did not add a GIF writing capability to GIFLib so that I (and
others) would not get into legal trouble with UNISYS.  You can buy commercial
code that will allow you to write GIF images if you need that capability.  You
might also search the web for ImageMagik, a freeware image viewer that comes
with source.  I copied (and rewrote) portions of the GIF decoder 
(GIFImage::ReadBits) from the ImageMagik source code.  ImageMagik includes an
encoder as well.

-------- Potentialy Useful Information ---------------------------------------

There are 2 classes defined in GIFLib.  GIFImage is a class that contains 
information about each individual image in a GIF file.  GIFData is a
class that contains all if the images in a GIF file.  GIFData is also 
responsible for cycling through the images if the GIF is animated.

Both static and animated GIF files can be displayed the same way.  The 
following example assumes that there is a global object declared as

	GIFData *gif;

An application can open a GIF by calling the following functions:

	char *fileName;	// the file name obtained by your app.
	HWND hWnd;	// the handle of the window that will display the 
			// image

	gif = new GIFData( hWnd ); 
	gif->ReadFile( fileName );
	gif->Animate();	// returns true if the GIF can be animated,
			// false otherwise.

The GIFData::Animate function determines if the file can be animated.  If the
file contains more than 1 image then GIFData creates a multimedia timer that
updates the image when needed.  The application must have a function that 
catches the WM_PAINT message.  That function should call one of the following
functions to draw the image.

	int Top, Left;	// the upper, left position of the image in the
			// window
	HDC hDC;	// the device context that the image will be drawn to
	float scale;	// a scale factor used to shrink/magnify the image

	gif->GetCurrentImage().BitBlt( Left, Top, hDC );

	or

	gif->GetCurrentImage().Stretch( Left, Top, scale, hDC );

Thats it.  The GIFData object and the multimedia timer will handle everything
else.

If you want to extract the image information from the GIF file without 
displaying the images, then call the following functions:

	char *fileName;	// the name of the GIF file obtained by your app.
	ColorStruct *table;	// a pointer to the image's color table
				// the ColorStruct structure is defined in 
				// GIFLib.h
	unsigned char **bits;	// a pointer to a 2-D array that contains
				// indices into the color table.  See comments
				// below for info about array format.

	gif = new GIFData( NULL); 
	gif->EnableBitmap( false );  // do not create an HBITMAP.  Must
				     // be called before ReadFile.
	gif->ReadFile( fileName );

	for ( unsigned i = 0; i < gif->GetNumImages(); i++ )
	{
		table = gif->GetImage(i).GetColorTable();
		bits = gif->GetImage(i).GetBits();
		// do your thing
	}


The dimensions of the bitmap and the color table are:

	unsigned h = gif->GetImage(i).GetHeight();
	unsigned w = gif->GetImage(i).GetScanLineWidth();
	unsigned char bits[h][w];
	unsigned short nc = gif->GetImage(i).GetNumColors();
	ColorStruct table[nc];

and each row of the array will have "packed" bitmap data as required by an
HBITMAP.  See the GIFImage::PackBits, GIFImage::SetPackedBit, 
and GIFImage::GetUnpackedBit functions and your online help (BITMAPINFO and
BITMAPINFOHEADER) for additional information about "packed" bitmap formats.

Working examples can be found in the BCB and MFC folders.

Enjoy...
Scott
July 27, 2001

scottheiman@home.com

BUG FIX: July 27, 2001
Fixed an error when reading local co;or tables.
