Microsoft Windows Metafile

Also Known As: WMF, Enhanced Metafile, EMF, APM


Type Metafile
Colors 24-bit
Compression None
Maximum Image Size NA
Multiple Images Per File Yes
Numerical Format Little-endian
Originator Microsoft Corporation
Platform Microsoft Windows
Supporting Applications Numerous Microsoft Windows-based graphics applications
See Also Encapsulated PostScript, Microsoft Windows Bitmap, and Microsoft Windows Clipboard

Usage
Storage of vector drawings and bitmaps.

Comments
A widely used format associated with Microsoft Windows, although many applications on other platforms provide support.


Microsoft Windows Metafile Format (WMF) files are used to store both vector and bitmap-format graphical data in memory or in disk files. The vector data stored in WMF files is described as Microsoft Windows Graphics Device Interface (GDI) commands. In the Window environment these commands are interpreted and played back on an output device using the Windows API PlayMetaFile() function. Bitmap data stored in a WMF file may be stored in the form of a Microsoft Device Dependent Bitmap (DDB), or Device Independent Bitmap (DIB).

Contents:
File Organization
File Details
For Further Information

In the Windows environment, metafiles are typically created and played back in memory. If the metafile data grows too large to be stored in memory, or needs to be saved before an application terminates, the data can be written to disk in the form of a WMF or EMF file and played back from disk. The maximum size of a Windows metafile is four gigabytes.

WMF is the original 16-bit Windows metafile format that appeared with Windows 2.0. EMF files are the 32-bit revision of the WMF format. EMF files have extended functionality over WMF files, including a color palette and full support for all 32-bit GDI commands. The Win32 API (Windows 95 and Windows NT) and 32-bit OLE support both WMF and EMF files. The Win16 and Win32s APIs (Windows 3.x) and 16-bit OLE only supports WMF files.

Although the Windows Metafile format is specific to Microsoft Windows, many non-Windows-based applications support this format as a method for interchanging graphical data with Windows applications. Because of the widespread popularity of the Microsoft Windows GUI, the Windows Metafile format has become a staple format for graphical applications and is therefore supported on most platforms. For example, Adobe's Encapsulated PostScript (EPS) supports the use of an included Windows Metafile when required to store vector-based data.

If you are using metafiles in the Windows or OS/2 operating systems you will not write code to parse them directly, but instead call a set of Windows API functions used to manipulate metafiles. Because there is ample documentation from Microsoft and IBM on how to use metafiles under Windows and OS/2, this article will look at the structure and direct parsing of Microsoft metafiles without the benefit of the Windows API.

If you have access to the Win16 Software Development Kit, then you will find all of the data structures and data type definitions associated with WMF files in the WINDOWS.H header file. For the Win32 SDK you will find WMF and EMF definitions in the WINUSER.H and WINGDI.H header files. Both of these SDKs are available with all C and C++ compilers that support Windows application development.

File Organization

A metafile is comprised of one or two information headers and an array of variable-length records that store the GDI function call information.

There are four flavors of Windows metafiles: standard, placeable, clipboard, and enhanced. A standard metafile contains an 18-byte WMF header followed by one or more records of GDI commands. A placeable metafile contains a 22-byte header followed by the standard 18-byte WMF header and GDI command records. Clipboard metafiles contains a 8-byte (Win16) or 16-byte (Win32) header that precedes the standard metafile header. Enhanced metafiles contain only EMF records, with the first record storing the header information. EMF files are not compatible in design with the other types of WMF metafiles.

Windows Metafiles (Figure Microsoft Windows Metafile-1) contain a header, followed by one or more records of data. The header contains a description of the record data stored in the metafile. Each record is a binary-encoded Microsoft Windows Graphics Device Interface (GDI) function call. The GDI is used by Windows to perform all output to a window, printer, or other output device. When the metafile data is rendered (or played back, in Microsoft terminology), the data from each record is used to perform the appropriate GDI function call to render each object stored in the file. The last record in the file contains information indicating that the end of the record data has been reached.

Figure Microsoft Windows Metafile-1: Standard metafile format

[Graphic: Figure Microsoft Windows Metafile-1]

Placeable metafiles (Figure Microsoft Windows Metafile-2) are WMF files with an 18-byte header prepended. This preheader contain information used to describe the position of the metafile drawing on the printed page (something that the original WMF file designers did not think of).

Figure Microsoft Windows Metafile-2: Placeable metafile format

[Graphic: Figure Microsoft Windows Metafile-2]

Clipboard metafiles (Figure Microsoft Windows Metafile-3) are similar to placeable metafiles in that that also contain an extra header prepended to a WMF file. The Clipboard preheader contains information used to describe the position of the metafile on the Windows Clipboard and the mapping mode used to playback the data.

Figure Microsoft Windows Metafile-3: Clipboard metafile format

[Graphic: Figure Microsoft Windows Metafile-3]

Enhanced metafiles (Figure Microsoft Windows Metafile-4) have the same basic format of WMF files: a header followed by one or more records of drawing objects stored as GDI commands. Unlike WMF, the header is also stored in a record which appears as the first record in each EMF file. The EMF header now contains additional information, including the position and mapping information stored in the placeable and clipboard metafile preheaders. EMF also adds the features of a file description string and a programmable color palette to the metafile format.

Figure Microsoft Windows Metafile-4: Enhanced metafile format

[Graphic: Figure Microsoft Windows Metafile-4]

File Details

The standard Windows metafile header is 18 bytes in length and is structured as follows:

typedef struct _WindowsMetaHeader
{
  WORD  FileType;       /* Type of metafile (0=memory, 1=disk) */
  WORD  HeaderSize;     /* Size of header in WORDS (always 9) */
  WORD  Version;        /* Version of Microsoft Windows used */
  DWORD FileSize;       /* Total size of the metafile in WORDs */
  WORD  NumOfObjects;   /* Number of objects in the file */
  DWORD MaxRecordSize;  /* The size of largest record in WORDs */
  WORD  NumOfParams;    /* Not Used (always 0) */
} WMFHEAD;

FileType contains a value which indicates the location of the metafile data. A value of 0 indicates that the metafile is stored in memory, while a 1 indicates that it is stored on disk.

HeaderSize contains the size of the metafile header in 16-bit WORDs. This value is always 9.

Version stores the version number of Microsoft Windows that created the metafile. This value is always read in hexadecimal format. For example, in a metafile created by Windows 3.0 and 3.1, this item would have the value 0x0300.

FileSize specifies the total size of the metafile in 16-bit WORDs.

NumOfObjects specifies the number of objects that are in the metafile.

MaxRecordSize specifies the size of the largest record in the metafile in WORDs.

NumOfParams is not used and is set to a value of 0.

Aldus Placeable Metafiles

Placeable Metafiles (file extension .APM) were created by Aldus Corporation as a non-standard way of specifying how a metafile is mapped and scaled on an output device. Placeable metafiles are quite wide-spread, but not directly supported by the Windows API. To playback a placeable metafile using the Windows API, you will first need to strip the placeable metafile header from the file. This is typically performed by copying the metafile to a temporary file starting at file offset 0x16. The contents of the temporary file may then be used as input to the Windows GetMetaFile(), PlayMetaFile(), CopyMetaFile(), etc. GDI functions. Placeable Metafiles are limited to 64K in length.

Each placeable metafile begins with a 22-byte header followed by a standard metafile:

typedef struct _PlaceableMetaHeader
{
  DWORD Key;           /* Magic number (always 9AC6CDD7h) */
  WORD  Handle;        /* Metafile HANDLE number (always 0) */
  SHORT Left;          /* Left coordinate in metafile units */
  SHORT Top;           /* Top coordinate in metafile units */
  SHORT Right;         /* Right coordinate in metafile units */
  SHORT Bottom;        /* Bottom coordinate in metafile units */
  WORD  Inch;          /* Number of metafile units per inch */
  DWORD Reserved;      /* Reserved (always 0) */
  WORD  Checksum;      /* Checksum value for previous 10 WORDs */
} PLACEABLEMETAHEADER;

Key contains a special identification value that indicates the presence of a placeable metafile header and is always 9AC6CDD7h.

Handle is used to stored the handle of the metafile in memory. When written to disk, this field is not used and will always contains the value 0.

Left, Top, Right, and Bottom contain the coordinates of the upper-left and lower-right corners of the image on the output device. These are measured in twips[1]. These four fields also correspond to the RECT structure used in Microsoft Windows and defined in the file WINDOWS.H.

[1] A twip (meaning "twentieth of a point") is the logical unit of measurement used in Windows Metafiles. A twip is equal to 1/1440 of an inch. Thus 720 twips equal 1/2 inch, while 32,768 twips is 22.75 inches.

Inch contains the number of twips per inch used to represent the image. Normally, there are 1440 twips per inch; however, this number may be changed to scale the image. A value of 720 indicates that the image is double its normal size, or scaled to a factor of 2:1. A value of 360 indicates a scale of 4:1, while a value of 2880 indicates that the image is scaled down in size by a factor of two. A value of 1440 indicates a 1:1 scale ratio.

Reserved is not used and is always set to 0.

Checksum contains a checksum value for the previous 10 WORDs in the header. This value can be in an attempt to detect if the metafile has become corrupted. The checksum is calculated by XORing each WORD value to an initial value of 0:

PLACEABLEMETAHEADER pmh; 
pmh.Checksum = 0;
pmh.Checksum ^= (pmh.Key & 0x0000FFFFUL);
pmh.Checksum ^= ((pmh.Key & 0xFFFF0000UL) >> 16);
pmh.Checksum ^= pmh.Handle; 
pmh.Checksum ^= pmh.Left;
pmh.Checksum ^= pmh.Top; 
pmh.Checksum ^= pmh.Right;
pmh.Checksum ^= pmh.Bottom; 
pmh.Checksum ^= pmh.Inch;
pmh.Checksum ^= (pmh.Reserved & 0x0000FFFFUL);
pmh.Checksum ^= ((pmh.Reserved & 0xFFFF0000UL) >> 16);

An alternative way to step through the header structure one WORD at a time is to use a pointer as shown below:

PLACEABLEMETAHEADER *pmh; 
WORD *ptr;
pmh->Checksum = 0;
for (ptr = (WORD *) pmh; ptr < (WORD *)pmh->Checksum; ptr++)
    pmh->Checksum ^= *ptr;

Clipboard Metafile

Clipboard metafiles are stored in Microsoft Clipboard Viewer files (file extension .CLP) and Microsoft Windows Write files (file extension .WRI). Clipboard metafiles are also based on the standard metafile format, but are preceded by an additional 8- or 16-byte header that allows the position of the metafile on the Clipboard viewer. If the Clipboard metafile was created using a 16-bit version of Windows (Windows and Windows for Workgroups) this header will contain 2-byte fields arranged in the following structure:

typedef struct _Clipboard16MetaHeader
{
  SHORT MappingMode; /* Units used to playback metafile */
  SHORT Width;       /* Width of the metafile */
  SHORT Height;      /* Height of the metafile */
  WORD  Handle;      /* Handle to the metafile in memory */
} CLIPBOARD16METAHEADER;

MappingMode specifies the type of Windows coordinate mapping units used to store and playback the metafile data. This field will contain one of the following values:

Value Mapping Mode One Unit Maps To
1 Text One pixel
2 Low Metric 0.1 millimeter
3 High Metric 0.01 millimeter
4 Low English 0.01 inch
5 High English 0.001 inch
6 Twips 1/1440th of an inch
7 Isotropic Application specific (aspect ratio preserved)
8 Anisotropic Application specific (aspect ratio not preserved)

Width and Height are the size of the metafile in the units specified in the MappingMode field.

Handle is used to stored the handle of the metafile in memory. When written to disk, this field is not used and will always contains the value 0.

If the clipboard metafile was created under a 32-bit Windows environment (Windows NT and Windows 95) this header will contain the same fields as the Win16 WMF header, but the fields are 32 bytes in length:

typedef struct _Clipboard32MetaHeader
{
  LONG  MappingMode; /* Units used to playback metafile */
  LONG  Width;       /* Width of the metafile */
  LONG  Height;      /* Height of the metafile */
  DWORD Handle;      /* Handle to the metafile in memory */
} CLIPBOARD32METAHEADER;

Enhanced Metafiles

Enhanced metafile files are a "new and improved" 32-bit revision of the standard metafile. Only the 32-bit Windows API (Win32) supports EMF files and the 16-bit Windows APIs (Win16 and Win32s) do not. It is also recommended that WMF files not be used by applications running the Window 32-bit environments (Windows 95 and Windows NT). Enhanced metafiles are typically saved to disk using the file extension ".EMF".

The string data found in EMF files uses the Unicode character set. Each Unicode character is 2-bytes in size. The first 256 (of the over 36000) characters of the Unicode characters set are also the 256 characters of the ANSI character set used by Windows. The low byte of each Unicode character will contain the ANSI character value and the high byte will be zero. You will recognize Unicode strings in data dumps when you see a byte pattern such as " S u m m a r y I n f o" rather than the more common ANSI or ASCII pattern of "SummaryInfo".

EMF files have a header that is 80 bytes in length and contains the same features as found in placeable and Clipboard metafiles. Although the header is considered to be just another EMF record, it must appear as the first record in every EMF file.

typedef struct _EnhancedMetaHeader
{
    DWORD RecordType;       /* Record type */
    DWORD RecordSize;       /* Size of the record in bytes */
    LONG  BoundsLeft;       /* Left inclusive bounds */
    LONG  BoundsRight;      /* Right inclusive bounds */
    LONG  BoundsTop;        /* Top inclusive bounds */
    LONG  BoundsBottom;     /* Bottom inclusive bounds */
    LONG  FrameLeft;        /* Left side of inclusive picture frame */
    LONG  FrameRight;       /* Right side of inclusive picture frame */
    LONG  FrameTop;         /* Top side of inclusive picture frame */
    LONG  FrameBottom;      /* Bottom side of inclusive picture frame */
    DWORD Signature;        /* Signature ID (always 0x464D4520) */
    DWORD Version;          /* Version of the metafile */
    DWORD Size;             /* Size of the metafile in bytes */
    DWORD NumOfRecords;     /* Number of records in the metafile */
    WORD  NumOfHandles;     /* Number of handles in the handle table */
    WORD  Reserved;         /* Not used (always 0) */
    DWORD SizeOfDescrip;    /* Size of description string in WORDs */
    DWORD OffsOfDescrip;    /* Offset of description string in metafile */
    DWORD NumPalEntries;    /* Number of color palette entries */
    LONG  WidthDevPixels;   /* Width of reference device in pixels */
    LONG  HeightDevPixels;  /* Height of reference device in pixels */
    LONG  WidthDevMM;       /* Width of reference device in millimeters */
    LONG  HeightDevMM;      /* Height of reference device in millimeters */
} ENHANCEDMETAHEADER;

RecordType identifies the type of EMF record. For the EMF header record this value is always 00000001h.

RecordSize is the size of the header in bytes.

BoundsLeft, BoundsRight, BoundsTop, and BoundsBottom specify the size of the metafile drawing using X, Y, width, and length coordinate system. BoundsTop and BoundsBottom must have greater values than BoundsLeft and BoundsRight.

FrameLeft, FrameRight, FrameTop, and FrameBottom specify the size of the frame or border that encloses the metafile using X, Y, width, and length coordinate system. FrameTop and FrameBottom must have greater values than FrameLeft and FrameRight.

Signature is a file identification value and is always set to the value of 0x464D4520.

Version is the version number of the EMF file format. The current version is 1.0 and is stored as the value 0x00000100.

Size is the size of the entire metafile in bytes.

NumOfRecords is the total number of records in the metafile, including the header record.

NumOfHandles is the number of handles currently stored in the memory handle table. This value is always 0 for metafile data stored to disk.

Reserved is not used and is always zero.

SizeOfDescrip is the number of 16-bit Unicode characters contained in the description string, including all NULL characters. If this value is 0 then no description string is present in the file.

OffsOfDescrip is the location of the description string calculated as the number of bytes from the beginning of the file. If this value is 0 then no description string is present in the file.

NumPalEntries indicates the number of entries in the color palette. The color palette, if present, will be located in the End-Of-File records. If this value is 0 then no color palette is present.

WidthDevPixels and HeightDevPixels are the width and height of the display device in pixels.

WidthDevMM and HeightDevMM are the width and height of the display device in millimeters.

EMF Description String

A Unicode description string may be stored in an EMF file. If the SizeOfDescrip and OffsOfDescrip header fields are not zero, then a description string is present in the file. It will be located OffsOfDescrip bytes from the beginning of the file and will contain SizeOfDescrip Unicode characters.

Although not limited in practical size (unless you want a description longer than two billion characters), the description string is expected to have a specific format. The format is the name of the application that created the picture, a NULL, the name or description of the picture, and finally two NULLs. A typical EMF creator/title Unicode description string may therefore appear as such:

"Pain Paint 1.5\0Eating at Polly's\0\0"

Adhering to this "double NULL-terminated format" guarantees that standard information may be obtained form an EMF file and also allows the description string to be easily read using Windows GDI function calls.

Standard Metafile Records

Following the standard header in all WMF metafiles is a series of data records. This record is defined by the METARECORD data type definition in WINDOWS.H and has the following format:

typedef struct _StandardMetaRecord
{
    DWORD Size;          /* Total size of the record in WORDs */
    WORD  Function;      /* Function number (defined in WINDOWS.H) */
    WORD  Parameters[];  /* Parameter values passed to function */
} WMFRECORD;

Size is the total size of the records in 16-bit WORDs, including the Size field itself. The minimum possible size for a record is 3.

Function is the GDI number of the function called to playback this record. The low-byte of this value identifies the specific GDI function to call. The high-byte is the number of WORDs passed to this function, and is also the number of elements in the Parameters array. For example, a value of 0x0213 indicates the LineTo() function (0x13) and that this function is passed two WORD values.

Parameters is an array of the parameters used by the GDI function specified by this record. The parameters are stored in the reverse order in which they are passed to the function. For example, the two parameter values of the LineTo record are passed to the LineTo() function in the order of X and Y, but store in the record as Y and X.

Although each record parameter is stored as a WORD, the exact data type of the parameter is determined by the function it is passed to. Parameter values that change, such as device context handles, are never stored in metafile records.

The last record in every metafile always has a function number of 0000h, a Size of 0003h, and no Parameters array. This record is used to indicate the end of the record data in the metafile. The use of this terminator record is missing from the original WMF description found in the Windows SDK and is now documented in article Q99334 of the Microsoft Knowledge Base.

When a Windows Metafile format file is played back in the Windows environment, each record is read and the function call it contains is executed in the sequence in which it is stored in the file. Windows creates a table of object handles used by the functions called in the metafile records. The maximum size of this object handle table is indicated by the value of the NumOfObjects field in the header. Windows inserts new objects into the table using the SelectObject() API call. The object handle table is only created and used during the access of the metafile in memory and is never stored in a WMF file.

There are several important considerations that must be observed when reading metafile record data.

Not all of the records in a Windows Metafile have the above format, although most do. The metafile records that do follow this basic record format are the following:

Record Name Function Number
AbortDoc 0x0052
Arc 0x0817
Chord 0x0830
DeleteObject 0x01f0
Ellipse 0x0418
EndDoc 0x005E
EndPage 0x0050
ExcludeClipRect 0x0415
ExtFloodFill 0x0548
FillRegion 0x0228
FloodFill 0x0419
FrameRegion 0x0429
IntersectClipRect 0x0416
InvertRegion 0x012A
LineTo 0x0213
MoveTo 0x0214
OffsetClipRgn 0x0220
OffsetViewportOrg 0x0211
OffsetWindowOrg 0x020F
PaintRegion 0x012B
PatBlt 0x061D
Pie 0x081A
RealizePalette 0x0035
Rectangle 0x041B
ResetDc 0x014C
ResizePalette 0x0139
RestoreDC 0x0127
RoundRect 0x061C
SaveDC 0x001E
ScaleViewportExt 0x0412
ScaleWindowExt 0x0410
SelectClipRegion 0x012C
SelectObject 0x012D
SelectPalette 0x0234
SetTextAlign 0x012E
SetBkColor 0x0201
SetBkMode 0x0102
SetDibToDev 0x0d33
SetMapMode 0x0103
SetMapperFlags 0x0231
SetPalEntries 0x0037
SetPixel 0x041F
SetPolyFillMode 0x0106
SetRelabs 0x0105
SetROP2 0x0104
SetStretchBltMode 0x0107
SetTextAlign 0x012E
SetTextCharExtra 0x0108
SetTextColor 0x0209
SetTextJustification 0x020A
SetViewportExt 0x020E
SetViewportOrg 0x020D
SetWindowExt 0x020C
SetWindowOrg 0x020B
StartDoc 0x014D
StartPage 0x004F

For example, the LineTo record stores information that is passed to the LineTo() GDI function. The LineTo() function draws a line from the current point to the coordinates specified in the record data. Assuming the line is to be drawn to location 100,50, the data in the LineTo record would appear as follows:

Size           5        /* Five WORDs in the file */
Function       0x0213   /* LineTo function number */
Parameters[0]  50       /* Y Coordinate */
Parameters[1]  100      /* X Coordinate */

This data would be read from the metafile and passed to the LineTo() GDI functions as such (the hDC handle is not stored in the metafile):

LineTo(hDC, 100, 5);    

Several record formats deviate from the basic record format by containing a data structure, rather than a data array, in the Parameters field. These records are:

Record Name Function Number
AnimatePalette 0x0436
BitBlt 0x0922
CreateBitmap 0x06FE
CreateBitmapIndirect 0x02FD
CreateBrush 0x00F8
CreateBrushIndirect 0x02FC
CreateFontIndirect 0x02FB
CreatePalette 0x00F7
CreatePatternBrush 0x01F9
CreatePenIndirect 0x02FA
CreateRegion 0x06FF
DeleteObject 0x01F0
DibBitblt 0x0940
DibCreatePatternBrush 0x0142
DibStretchBlt 0x0B41
DrawText 0x062F
Escape 0x0626
ExtTextOut 0x0A32
Polygon 0x0324
PolyPolygon 0x0538
Polyline 0x0325
TextOut 0x0521
StretchBlt 0x0B23
StretchDIBits 0x0F43

For example, the BitBlt record is used to store bitmap data in a metafile. The BitBlt record stores a Device Dependent Bitmap (DDB) in its Parameters field. A DDB is a simple header followed by uncompressed bitmap data. The entire BitBlt record in a Windows 2.x metafile will have the following format:

typedef struct _BitBltRecord
{
    DWORD     Size;             /* Total size of the record in WORDs */
    WORD      Function;         /* Function number (0x0922) */
    WORD      RasterOp;         /* High-order word for the raster operation */
    WORD      YSrcOrigin;       /* Y-coordinate of the source origin */
    WORD      XSrcOrigin;       /* X-coordinate of the source origin */
    WORD      YDest;            /* Destination width */
    WORD      XDest;            /* Destination height */
    WORD      YDestOrigin;      /* Y-coordinate of the destination origin */
    WORD      XDestOrigin;      /* X-coordinate of the destination origin */
    /* DDB Bitmap */
    DWORD     Width;            /* Width of bitmap in pixels */
    DWORD     Height;           /* Height of bitmap in scan lines */
    DWORD     BytesPerLine;     /* Number of bytes in each scan line */
    WORD      NumColorPlanes;   /* Number of color planes in the bitmap */
    WORD      BitsPerPixel;     /* Number of bits in each pixel */
    RGBTRIPLE Bitmap[];         /* Bitmap data */
} BITBLTRECORD;

The bitmap data itself is stored as an array of RGBTRIPLE structures:

typedef struct _RGBTriple
{
    BYTE Red;
    BYTE Green;
    BYTE Blue;
} RGBTRIPLE;

Note that DDB bitmap found in Windows 2.x WMF BitBlt records is not compatible with Windows 3.0 and later. Windows 3.0 created the DibBitBlt record to store a Device Independent Bitmap (DIB) rather than a DDB. A DibBitBlt record has the following format:

typedef struct _DibBitBltRecord
{
    DWORD   Size;             /* Total size of the record in WORDs */
    WORD    Function;         /* Function number (0x0940) */
    WORD    RasterOp;         /* High-order word for the raster operation */
    WORD    YSrcOrigin;       /* Y-coordinate of the source origin */
    WORD    XSrcOrigin;       /* X-coordinate of the source origin */
    WORD    YDest;            /* Destination width */
    WORD    XDest;            /* Destination height */
    WORD    YDestOrigin;      /* Y-coordinate of the destination origin */
    WORD    XDestOrigin;      /* X-coordinate of the destination origin */
    /* DIB Bitmap */
    DWORD   Width;            /* Width of bitmap in pixels */
    DWORD   Height;           /* Height of bitmap in scan lines */
    DWORD   BytesPerLine;     /* Number of bytes in each scan line */
    WORD    NumColorPlanes;   /* Number of color planes in the bitmap */
    WORD    BitsPerPixel;     /* Number of bits in each pixel */
    DWORD   Compression;      /* Compression type */
    DWORD   SizeImage;        /* Size of bitmap in bytes */
    LONG    XPelsPerMeter;    /* Width