To give you some idea about what to expect when looking at bitmap headers, we'll take a look at three typical ones. We'll start with one of the least complex (Microsoft Windows Bitmap), and proceed to two that are more complex (Sun Raster and Kofax raster).
To do this, we'll provide a C data structure, which will provide an idea of the size and relative position of each field in the headers.
// // Header structure for the MS Windows 1.x Bitmap Format // a BYTE is an unsigned char // a WORD is an unsigned short int (16-bits) // typedef struct _WinHeader1x { // // Type Name Offset Comment // WORD Type; /* 00h File Type Identifier (always 0) */ WORD Width; /* 02h Width of Bitmap in Pixels */ WORD Height; /* 04h Height of Bitmap in Scan-lines */ WORD Width; /* 06h Width of Bitmap in Bytes */ BYTE Planes; /* 08h Number of Color Planes */ BYTE BitsPixel; /* 09h Number of Bits Per Pixel */ } OLDWINHEAD;
As you can see from the comments, this particular header contains a file identification value, the width and height of the image, the width of a single line of the image (in bytes), the number of color planes, and the number of bits per pixel. This information is close to the bare minimum required to describe a bitmap image so it can be read and rendered in an arbitrary environment.
Note that the Windows 1.x header contains no information about color or image data compression. A more advanced image format will have provisions for both color information and at least a simple compression scheme. An example of a more elaborate header is that found in the Sun Raster image file format shown in the next example:
// // Header structure for the Sun Raster Image File Format // a WORD here is an unsigned long int (32 bits) // typedef struct _SunRasterHead { // // Type Name Offset Comment // WORD Magic; /* 00h Magic Number (59a66a95h) */ WORD Width; /* 04h Width of Image in Pixels */ WORD Height; /* 08h Height of Image in Pixels */ WORD Depth; /* 0Ch Number of Bits Per Pixel */ WORD Length; /* 10h Length of Image in Bytes */ WORD Type; /* 14h File Format Encoding Type */ WORD MapType; /* 18h Type of Color Map */ WORD MapLength; /* 1Ch Length of Color Map in Bytes */ } SUNRASHEAD;
The Sun Raster header contains information similar to the Windows 1.x bitmap header illustrated above. But note that it also contains fields for the type of data encoding method and the type and size of the color map or palette associated with the bitmap data.
Neither of the two headers mentioned above contains a text description field. One such header that does is that associated with the Kofax Image File Format shown in Example 3.
// // Header structure for the Kofax Raster Image File Format // a LONG is a signed long int (32 bits) // a SHORT is a signed short int (16 bits) // typedef struct _KofaxHeader { // // Type Name Offset Comment // LONG Magic; /* 00h Magic Number (68464B2Eh) */ SHORT HeaderSize; /* 04h Header Size */ SHORT HeaderVersion; /* 06h Header Version Number */ LONG ImageId; /* 0Ah Image Identification Number */ SHORT Width; /* 0Ch Image Width in Bytes */ SHORT Length; /* 0Eh Image Length in Scan-lines */ SHORT Format; /* 10h Image Data Code (Encoding) */ CHAR Bitsex; /* 11h Non-zero if Bitsex Reversed */ CHAR Color; /* 12h Non-zero if Color Inverted */ SHORT Xres; /* 14h Horizontal Dots Per Inch */ SHORT Yres; /* 16h Vertical Dots Per Inch */ CHAR Planes; /* 18h Number of Planes */ CHAR BitsPerPixel; /* 19h Number of Bits Per Pixel */ SHORT PaperSize; /* 1Ah Original Paper Size */ CHAR Reserved1[20]; /* 1Ch 20-byte Reserved Field */ LONG Dcreated; /* 30h Date Created */ LONG Dmodified; /* 34h Date Modified */ LONG Daccessed; /* 38h Date Accessed */ CHAR Reserved2[4]; /* 3Ch 4-Byte Reserved Field */ LONG Ioffset; /* 40h Index Text Info Offset */ LONG Ilength; /* 44h Index Text Info Length */ LONG Coffset; /* 48h Comment Text Offset */ LONG Clength; /* 4Ch Comment Text Length in Bytes */ LONG Uoffset; /* 50h User Data Offset */ LONG Ulength; /* 54h User Data Length in Bytes */ LONG Doffset; /* 58h Image Data Offset */ LONG Dlength; /* 5Ch Image Data Length in Bytes */ CHAR Reserved3[32]; /* 60h 32-byte Reserved Field */ } KFXHEAD;
Note that the Kofax header is considerably larger than either the Windows bitmap or Sun raster headers. Included are fields which describe the horizontal and vertical resolution, paper size of the image subject, offset values of different types of data stored in the file, and the time and date that the image was created, last modified, and accessed.
Also note the appearance of several fields marked reserved. The Kofax format header is intentionally padded to 128 bytes to accommodate common read and write buffer sizes. It uses only 72 bytes of the header in the revision presented here, but is padded to 128 bytes. The Kofax format specification promises that the first 128 bytes of every Kofax image file will be the header, regardless of future revisions. Applications are thus free to ignore the reserved data, and the format is presumably designed to allow this without dire penalty. See the general discussion of reserved fields in the section called "Unused Space" earlier in this chapter.
Header reading speed can be optimized by looking at the ways in which your application uses the data, because reading the header data can usually be performed in several ways. If only selected values in the header are needed, the application can calculate the offset of the data from some key landmark such as the start of the file. The application can then seek directly to the data value required and read the data value. The offset values appearing in the comments in the header examples above can be used as offset arguments for the seek function used.
If most of the data contained in the header is needed by the application, then it may be more convenient to read the entire header into a buffer or pre-allocated data structure. This can be performed quickly, taking advantage of any efficiencies provided by an integral-power-of-two block reads, as mentioned above. All of the header data will be available in memory and can be cached for use when needed. One problem, however, occurs when the byte order of the file is different from the native byte order of the system on which the file is being read. Most block read functions, for example, are not designed to supply automatic conversion of data. Another problem may arise when data structures are padded by the compiler or runtime environment for purposes of data member alignment. These problems and others are discussed in more detail in Chapter 6, Platform Dependencies.
Copyright © 1996, 1994 O'Reilly & Associates, Inc. All Rights Reserved.