An .ICL file -- ICon Library, as used by icon editors like Microangelo -- is a renamed 16-bit Windows .DLL (an NE format executable) which typically contains nothing but a resource section.
The ICL extension seems to be used by convention.
Icon Library .ICL File Format
.WMF Metafile Format
.WMF Metafile Format
A metafile for the Microsoft Windows operating system consists of a collection of graphics device interface (GDI) functions that describe an image. Because metafiles take up less space and are more device-independent than bitmaps, they provide convenient storage for images that appear repeatedly in an application or need to be moved from one application to another. To generate a metafile, a Windows application creates a special device context that sends GDI commands to a file or memory for storage. The application can later play back the metafile and display the image. During playback, Windows breaks the metafile down into records and identifies each object with an index to a handle table. When a META_DELETEOBJECT record is encountered during playback, the associated object is deleted from the handle table. The entry is then reused by the next object that the metafile creates. To ensure compatibility, an application that explicitly manipulates records or builds its own metafile should manage the handle table in the same way. For more information on the format of the handle table, see the HANDLETABLE structure.
In some cases, there are two variants of a metafile record, one representing the record created by Windows versions before 3.0 and the second representing the record created by Windows versions 3.0 and later. Windows versions 3.0 and later play all metafile versions but store only 3.0 and later versions. Windows versions earlier than 3.0 do not play metafiles recorded by Windows versions 3.0 and later. A metafile consists of two parts: a header and a list of records. The header and records are described in the remainder of this topic. For a list of function-specific records, see Metafile Records.
Metafile Header
The metafile header contains a description of the size of the metafile and the number of drawing objects it uses. The drawing objects can be pens, brushes, bitmaps, or fonts.
The metafile header has the following form:
typedef struct tagMETAHEADER {
WORD mtType;
WORD mtHeaderSize;
WORD mtVersion;
DWORD mtSize;
WORD mtNoObjects;
DWORD mtMaxRecord;
WORD mtNoParameters;
} METAHEADER;
Following are the members in the metafile header:
mtType | Specifies whether the metafile is stored in memory or recorded in a file. This member has one of the following values: 0 : Metafile is in memory. 1 : Metafile is in a file. |
mtHeaderSize | Specifies the size, in words, of the metafile header. |
mtVersion | Specifies the Windows version number. The version number for Windows version 3.0 and later is 0x300. |
mtSize | Specifies the size, in words, of the file. |
mtNoObjects | Specifies the maximum number of objects that can exist in the metafile at the same time. |
mtMaxRecord | Specifies the size, in words, of the largest record in the metafile. |
mtNoParameters | Not used. |
Typical Metafile Record
The graphics device interface stores most of the GDI functions that an application can use to create metafiles in typical records.
A typical metafile record has the following form:
struct {
DWORD rdSize;
WORD rdFunction;
WORD rdParm[];
}
Following are the members in a typical metafile record:
rdSize | Specifies the size, in words, of the record. |
rdFunction | Specifies the function number. This value may be the number of any function in the table at the end of this section. |
rdParm | Identifies an array of words containing the function parameters (listed in the reverse order in which they are passed to the function). |
Following are the GDI functions found in typical records, along with their hexadecimal values:
GDI function | Value |
Arc | 0x0817 |
Chord | 0x0830 |
Ellipse | 0x0418 |
ExcludeClipRect | 0x0415 |
FloodFill | 0x0419 |
IntersectClipRect | 0x0416 |
LineTo | 0x0213 |
MoveTo | 0x0214 |
OffsetClipRgn | 0x0220 |
OffsetViewportOrg | 0x0211 |
OffsetWindowOrg | 0x020F |
PatBlt | 0x061D |
Pie | 0x081A |
RealizePalette (3.0 and later) | 0x0035 |
Rectangle | 0x041B |
ResizePalette (3.0 and later) | 0x0139 |
RestoreDC | 0x0127 |
RoundRect | 0x061C |
SaveDC | 0x001E |
ScaleViewportExt | 0x0412 |
ScaleWindowExt | 0x0400 |
SetBkColor | 0x0201 |
SetBkMode | 0x0102 |
SetMapMode | 0x0103 |
SetMapperFlags | 0x0231 |
SetPixel | 0x041F |
SetPolyFillMode | 0x0106 |
SetROP2 | 0x0104 |
SetStretchBltMode | 0x0107 |
SetTextAlign | 0x012E |
SetTextCharacterExtra | 0x0108 |
SetTextColor | 0x0209 |
SetTextJustification | 0x020A |
SetViewportExt | 0x020E |
SetViewportOrg | 0x020D |
SetWindowExt | 0x020C |
SetWindowOrg | 0x020B |
Placeable Windows Metafiles
A placeable Windows metafile is a standard Windows metafile that has an additional 22-byte header. The header contains information about the aspect ratio and original size of the metafile, permitting applications to display the metafile in its intended form.
The header for a placeable Windows metafile has the following form:
typedef struct {
DWORD key;
HANDLE hmf;
RECT bbox;
WORD inch;
DWORD reserved;
WORD checksum;
} METAFILEHEADER;
Following are the members of a placeable metafile header:
key | Specifies the binary key that uniquely identifies this file type. This member must be set to 0x9AC6CDD7L. |
hmf | Unused; must be zero. |
bbox | Specifies the coordinates of the smallest rectangle that encloses the picture. The coordinates are in metafile units as defined by the inch member. |
inch | Specifies the number of metafile units to the inch. To avoid numeric overflow, this value should be less than 1440. Most applications use 576 or 1000. |
reserved | Unused; must be zero. |
checksum | Specifies the checksum. It is the sum (using the XOR operator) of the first 10 words of the header. |
The actual content of the Windows metafile immediately follows the header. The format for this content is identical to that for
standard Windows metafiles. For some applications, a placeable indows metafile must not exceed 64K.
Note: Placeable Windows metafiles are not compatible with the GetMetaFile function. Applications that intend to use the metafile functions to read and play placeable Windows metafiles must read the file by using an input function (such as _lread), strip the 22-byte header, and create a standard Windows metafile by using the remaining bytes and the SetMetaFileBits function.
Guidelines for Windows Metafiles
To ensure that metafiles can be transported between different computers and applications, any application that creates a metafile should make sure the metafile is device-independent and sizable.
The following guidelines ensure that every metafile can be accepted and manipulated by other applications:
- Set a mapping mode as one of the first records. Many applications, including OLE applications, only accept metafiles that are in MM_ANISOTROPIC mode.
- Call the SetWindowOrg and SetWindowExt functions. Do not call the SetViewportExt or SetViewportOrg functions if the user will be able to resize or change the dimensions of the object.
- Use the MFCOMMENT printer escape to add comments to the metafile.
- Rely primarily on the functions listed in Typical Metafile Record. Observe the following limitations on the functions you use:
- Do not use functions that retrieve data (for example, GetActiveWindow or EnumFontFamilies).
- Do not use any of the region functions (because they are device dependent).
- Use StretchBlt or StretchDIB instead of BitBlt.
Sample of Metafile Program Output
This section describes a sample program and the metafile that it creates. The sample program creates a small metafile that draws a purple rectangle with a green border and writes the words "Hello People" in the rectangle.
MakeAMetaFile(hDC)
HDC hDC;
{
HPEN hMetaGreenPen;
HBRUSH hMetaVioletBrush;
HDC hDCMeta;
HANDLE hMeta;
/* Create the metafile with output going to the disk. */
hDCMeta = CreateMetaFile( (LPSTR) "sample.met");
hMetaGreenPen = CreatePen(0, 0, (DWORD) 0x0000FF00);
SelectObject(hDCMeta, hMetaGreenPen);
hMetaVioletBrush = CreateSolidBrush((DWORD) 0x00FF00FF);
SelectObject(hDCMeta, hMetaVioletBrush);
Rectangle(hDCMeta, 0, 0, 150, 70);
TextOut(hDCMeta, 10, 10, (LPSTR) "Hello People", 12);
/* We are done with the metafile. */
hMeta = CloseMetaFile(hDCMeta);
/* Play the metafile that we just created. */
PlayMetaFile(hDC, hMeta);
}
The resulting metafile, SAMPLE.MET, consists of a metafile header and six records. It has the following binary form:
0001 mtType... disk metafile
0009 mtSize...
0300 mtVersion
0000 0036 mtSize
0002 mtNoObjects
0000 000C mtMaxRecord
0000 mtNoParameters
0000 0008 rdSize
02FA rdFunction (CreatePenIndirect function)
0000 0000 0000 0000 FF00 rdParm (LOGPEN structure defining pen)
0000 0004 rdSize
012D rdFunction (SelectObject)
0000 rdParm (index to object #0... the above pen)
0000 0007 rdSize
02FC rdFunction (CreateBrushIndirect)
0000 00FF 00FF 0000 rdParm (LOGBRUSH structure defining the brush)
0000 0004 rdSize
012D rdFunction (SelectObject)
0001 rdParm (index to object #1... the brush)
0000 0007 rdSize
041B rdFunction (Rectangle)
0046 0096 0000 0000 rdParm (parameters sent to Rectangle...
in reverse order)
0000 000C rdSize
0521 rdFunction (TextOut)
rdParm
000C count
string
48 65 6C 6C 6F 20 50 65 6F 70 6C 65 "Hello People"
000A y-value
000A x-value
ZSoft PCX File Format
Image files used by PC Paintbrush product family and FRIEZE (those with a
.PCX extension) begin with a 128 byte header. Usually you can ignore this
header, since your images will probably all have the same resolution. If
you want to process different resolutions or colors, you will need to
interpret the header correctly. The remainder of the image file consists
of encoded graphic data. The encoding method is a simple byte oriented
run-length technique. We reserve the right to change this method to
improve space efficiency. When more than one color plane is stored in
the file, each line of the image is stored by color plane (generally ordered
red, green, blue, intensity), As shown below.
Scan line 0: RRR... (Plane 0)
GGG... (Plane 1)
BBB... (Plane 2)
III... (Plane 3)
Scan line 1: RRR...
GGG...
BBB...
III... (etc.)
The encoding method is:
FOR each byte, X, read from the file
IF the top two bits of X are 1's then
count = 6 lowest bits of X
data = next byte following X
ELSE
count = 1
data = X
Since the overhead this technique requires is, on average, 25% of
the non-repeating data and is at least offset whenever bytes are repeated,
the file storage savings are usually considerable.
ZSoft .PCX FILE HEADER FORMAT
Byte | Item | Size | Description/Comments |
0 | Manufacturer | 1 | Constant Flag, 10 = ZSoft .pcx |
1 | Version | 1 | Version information 0 = Version 2.5 of PC Paintbrush 2 = Version 2.8 w/palette information 3 = Version 2.8 w/o palette information 4 = PC Paintbrush for Windows(Plus for Windows uses Ver 5) 5 = Version 3.0 and > of PC Paintbrush and PC Paintbrush +, includes Publisher's Paintbrush . Includes 24-bit .PCX files |
2 | Encoding | 1 | 1 = .PCX run length encoding |
3 | BitsPerPixel | 1 | Number of bits to represent a pixel (per Plane) : 1, 2, 4, or 8 |
4 | Window | 8 | Image Dimensions: Xmin,Ymin,Xmax,Ymax |
12 | HDpi | 2 | Horizontal Resolution of image in DPI* |
14 | VDpi | 2 | Vertical Resolution of image in DPI* |
16 | Colormap | 48 | Color palette setting, see text |
64 | Reserved | 1 | Should be set to 0. |
65 | NPlanes | 1 | Number of color planes |
66 | BytesPerLine | 2 | Number of bytes to allocate for a scanline plane. MUST be an EVEN number. Do NOT calculate from Xmax-Xmin. |
68 | PaletteInfo | 2 | How to interpret palette- 1 = Color/BW, 2 = Grayscale (ignored in PB IV/ IV +) |
70 | HscreenSize | 2 | Horizontal screen size in pixels. New field found only in PB IV/IV Plus |
72 | VscreenSize | 2 | Vertical screen size in pixels. New field found only in PB IV/IV Plus |
74 | Filler | 54 | Blank to fill out 128 byte header. Set all bytes to 0 |
NOTES:
- All sizes are measured in BYTES.
- All variables of SIZE 2 are integers.
- *) HDpi and VDpi represent the Horizontal and Vertical resolutions which the image was created (either printer or scanner); i.e. an image which was scanned might have 300 and 300 in each of these fields.
Decoding .PCX Files
First, find the pixel dimensions of the image by calculating
[XSIZE = Xmax - Xmin + 1]
and [YSIZE = Ymax - Ymin + 1]
. Then calculate how many bytes are required to hold one complete uncompressed scan line: TotalBytes = NPlanes * BytesPerLine
Note that since there are always an even number of bytes per scan line, there will probably be unused data at the end of each scan line. TotalBytes shows how much storage must be available to decode each scan line, including any blank area on the right side of the image. You can now begin decoding the first scan line - read the first byte of data from the file. If the top two bits are set, the remaining six bits in the byte show how many times to duplicate the next byte in the file. If the top two bits are not set, the first byte is the data itself, with a count of one.
Continue decoding the rest of the line. Keep a running subtotal of how many bytes are moved and duplicated into the output buffer. When the subtotal equals TotalBytes, the scan line is complete. There should always be a decoding break at the end of each scan line. But there will not be a decoding break at the end of each plane within each scan line. When the scan line is completed, there may be extra blank data at the end of each plane within the scan line. Use the XSIZE and YSIZE values to find where the valid image data is. If the data is multi-plane, BytesPerLine shows where each plane ends within the scan line.
Continue decoding the remainder of the scan lines (do not just read to end-of-file). There may be additional data after the end of the image (palette, etc.)
Palette Information Description
EGA/VGA 16 Color Palette Information
In standard RGB format (IBM EGA, IBM VGA) the data is stored as 16 triples.
Each triple is a 3 byte quantity of Red, Green, Blue values. The values can
range from 0-255, so some interpretation may be necessary. On an IBM EGA,
for example, there are 4 possible levels of RGB for each color. Since
256/4 = 64, the following is a list of the settings and levels:
Setting Level
0-63 0
64-127 1
128-192 2
193-254 3
VGA 256 Color Palette Information
ZSoft has recently added the capability to store palettes containing more than 16 colors in the .PCX image file. The 256 color palette is formatted and treated the same as the 16 color palette, except that it is substantially longer. The palette (number of colors x 3 bytes in length) is appended to the end of the .PCX file, and is preceded by a 12 decimal. Since the VGA device expects a palette value to be 0-63 instead of 0-255, you need to divide the values read in the palette by 4.
To access a 256 color palette:
- First, check the version number in the header; if it contains a 5 there is
a palette. - Second, read to the end of the file and count back 769 bytes. The value you find should be a 12 decimal, showing the presence of a 256 color palette.
24-Bit .PCX Files
24 bit images are stored as version 5 or above as 8 bit, 3 plane images.
24 bit images do not contain a palette. Bit planes are ordered as lines of red, green, blue in that order.
CGA Color Palette Information
NOTE: This is no longer supported for PC Paintbrush IV/IV Plus.
For a standard IBM CGA board, the palette settings are a bit more complex.
Only the first byte of the triple is used. The first triple has a valid
first byte which represents the background color. To find the background,
take the (unsigned) byte value and divide by 16. This will give a result
between 0-15, hence the background color. The second triple has a valid
first byte, which represents the foreground palette. PC Paintbrush supports
8 possible CGA palettes, so when the foreground setting is encoded between
0 and 255, there are 8 ranges of numbers and the divisor is 32.
CGA Color Map
Header Byte #16: Background color is determined in the upper four bits.
Header Byte #19: Only upper 3 bits are used, lower 5 bits are ignored. The first three bits that are used are ordered C, P, I. These bits are interpreted as follows:
c: color burst enable - 0 = color; 1 = monochrome
p: palette - 0 = yellow; 1 = white
i: intensity - 0 = dim; 1 = bright