On (16 Mar 97) Paul Maddox wrote to Jerry Coffin...
PM> Hi Jerry.
Hello,
JC> Anyway, in both cases, you've basically got a header that
JC> tells you the size of the picture and a few things like that,
JC> a bunch of bytes that make up the image, and in some cases
PM> Do you have any very specific info?
A .bmp file is laid out like this:
struct BITMAPFILEHEADER {
unsigned int type; // must be set to 'BM'
unsigned long size; // size of bitmap in dwords
unsigned long ignore; // must be 0
unsigned long start_offset; // offset from this header to the
// beginning of the actual bitmap
};
enum compression_types {
BI_RGB, // uncompressed
BI_RLE8, // 8 bit RLE
BI_RLE4 // 4 bit RLE
};
struct BITMAPINFOHEADER {
unsigned long size; // size of this struct in bytes.
long width; // width of bitmap in pixels.
// The height of the bitmap is the absolute value of the following
// field. If `height' is positive, the origin is the lower left corner
// of the bitmap. If it's negative, the origin is the upper left
// corner.
long height;
unsigned short planes; // must be set to 1.
unsigned short bit_count; // bits/pixel [1, 4, 8, 16, 24, 32]
unsigned long compression; // specifies compression type.
unsigned long image_size; // size of image in bytes - 0 if
// uncompressed.
// The next two specify the desired resolution of the display device.
// This can be used to choose among a number of images, if you have more
// than one. Most programs just ignore it...
long x_pixels_per_meter;
long y_pixels_per_meter;
unsigned long colors_used; // see note below.
// The following is useful primarily for palette management in Windows.
unsigned long important_colors;
};
/* If `colors_used' is set to a non-zero value, it means only that many
* entries are used in the palette. Otherwise, the palette contains as
* many entries as needed for the number of bits in the bitmap. E.g.
* 8 bits/pixel means 256 entries if colors_used is 0, but 128 entries
* if colors_used is 128.
*/
struct RGBQUAD {
// should be pretty self explanatory.
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char junk;
};
// finally the conceptual structure of the file itself. This won't
// compile as-is, because we haven't specified sizes of the palette
// and bitmap, which we don't know until we read the preceding header
// info.
struct bmp_file {
BITMAPFILEHEADER header;
BITMAPINFOHEADER info;
RGBQUAD palette[]; // not present in 24 bit bitmaps.
unsigned char bitmap[];
};
As-is, this won't read _all_ .BMP files - there are other formats that
have different signatures than "BM" like this uses, and they can use
different formats entirely. For instance, OS/2 has a couple of bitmap
formats that are conceptually similar to this, and use essentially the
same BITMAPFILEHEADER, so it's possible figure out what sort of file
you're dealing with and read any of them. However, in my experience
this format is FAR more common than all the other variations put
together.
I don't have space left to go into the methods they use for RLE
compression - I'll have to hit that in another message.
Later,
Jerry.
... The Universe is a figment of its own imagination.
--- PPoint 1.90
---------------
* Origin: Point Pointedly Pointless (1:128/166.5)
|