Code   InformationDownload
Information Jpeg Library.

Before you read anymore you should check out the Readme in the download, it tells you (in case you hadn't already guessed) that more or less none of this code is mine, plus all sorts of other legal malarkey. Here's some highlights.

This software is Copyright © 1991-1996, Thomas G. Lane.
All Rights Reserved except as specified below.
I'm probably also required to state that;
The Graphics Interchange Format © is the Copyright property of CompuServe Incorporated. GIFsm is a Service Mark property of CompuServe Incorporated.

Basically, I was looking for a way to handle JPEGs in my C code and I found this really complex stuff from the "Independent JPEG Group". Good work clever-graphics-handling fellas. I don't understand the code but by hacking around (and following the instructions they gave me, duh) I've managed to turn it into a Win32 DLL. Just include the "gfxlib.h" file in your source and link with "gfxlib.lib" which will import "gfxlib.dll". The functions you'll be wanting to know about are these. Have a look below for just how dodgy this code is.

BOOL LoadFileGraphic(
   HDC hdc,
   char* lpPath,
   POINT* lpSize,
   HPALETTE* lpPal,
   HBITMAP* lpBmp,
   BOOL bShowErr
);

The easiest way to load a graphic. Give it a device context, the name of the file to load (JPEG,GIF or 256 color uncompressed bitmaps only), the address of a POINT structure which will be filled with the size of the picture that gets loaded, a pointer to a palette handle which will be filled with the handle of a logical palette for the loaded picture, a pointer to the bitmap handle you want to be filled with the picture, and a flag to tell the library whether or not to display it's own errors. That's all you need. If the picture gets loaded then it'll return TRUE, otherwise it'll return FALSE. The Draw... functions below give you easy ways to display what you've loaded.

BOOL LoadGraphicToBuffer(
   char* lpPath,
   BITMAPINFO* bi,
   LOGPALETTE* pal,
   HGLOBAL* hbits,
   BOOL lShowErr
);

This loads the picture in to a kind of 'raw' state which you can do what you like with. This is a bit trickier to use, see the web demo for an example of it in use. The lpPath is (fairly obviously) the file you want to load and the lShowErr flag does the same as in LoadFileGraphic. You've also got to give it the address of BITMAPINFO and LOGPALETTE structures, and also a pointer to a global handle. I tell you what, here's a snippet of code.
   
  ...
#include "gfxlib.h"
...
struct{
   BITMAPINFOHEADER bmiHeader;
   RGBQUAD bmiColors[256];
} bi;
struct{
   WORD palVersion;
   WORD palNumEntries;
   PALETTEENTRY palPalEntry[256];
} pal;
HGLOBAL hbits = NULL;
...
LoadGraphicToBuffer(
   "image.jpg\0",
   (BITMAPINFO*)&bi,
   (LOGPALETTE*)&pal,
   &hbits,
   TRUE
);
...
 
     


void DrawBitmap(
   HDC hdc,
   int x,
   int y,
   HPALETTE hPal,
   HBITMAP hBmp
);

This is the easiest way to display a bitmap. Just pass in the device context you want it on, the x and y positions on that device, a handle to the logical palette (created by LoadFileGraphic if you like) and a handle to the bitmap to draw (you might want to use the one from LoadFileGraphic!). And that's it. Yippee.

void DrawBitmapEx(
   HDC hdc,
   int x,
   int y,
   HPALETTE hPal,
   HBITMAP hBmp,
   int nSize,
   int nMask,
   HBITMAP hBkBmp,
   BOOL bFrame
);

This is an extended bitmap drawing function. The first four parameters are the same as DrawBitmap, then it goes a bit weird.
nSize is the size to draw the image (as a percentage of the original).
nMask is the 'amount' of the image to draw, 0 won't draw anything 100 draws it as normal, anything in between uses a kind of dissolvey effect to mix the image with the background. Which brings us on to...
hBkBmp is a handle to the bitmap to use as the background for any dissolving effects. If this is NULL then a plain black bitmap is used as the background.
bFrame draws a single pixel black frame around the image if this is set to TRUE.

The eagle eyed amongst you might have noticed that the arrays defined in the code snippet above only have 256 entries in them. Hoi, JPEGs can have loads of colors in them. Sorry chief, for simplicity (I am quite simple) everything gets converted down to 256 colors, it seems to look OK in most cases. This is why the functions have HPALETTEs passed about all over the shop.

Also, the support for BMPs is cack. This is 'cos I wrote that myself. It can only handle 256 color, uncompressed Windows bitmaps. In fact, this is what everything gets converted into eventually. I'm dumb, it's the only file format I can understand (although PPMs are quite easy too).

Finally. The GIF support is really dodgy, in fact I think it's probably illegal. It uses code that IJG supplied (but which they've now, quite rightly, removed. So don't blame them) to convert the GIF into a temporary JPEG file and then loads that in the normal way before deleting it. Oooh, highly efficient.

Sorry to the IJG for butchering your lovely code like this. It's all my fault. Please don't take me to court. If you're at all interested in using this stuff I would strongly suggest getting the proper version of the code from the places shown in the Readme file. Don't use my stuff, it's rubbish and you're probably breaking the law.

 




G.E.M