WPG
Usage Used for storage of document and image data.
Comments WPG is supported by other applications mainly for compatibility, due to the widespread distribution of WordPerfect for MS-DOS.
The WordPerfect Graphics Metafile (WPG) file format is a creation of WordPerfect Corporation (WPC) specifically for use with its line of software products. WPG image files are likely to be found in any environment that is supported by WPC products, including MS-DOS, UNIX, and the Apple Macintosh.
Contents: File Organization File Details For Further Information
WPG files are capable of storing both bitmap and vector data, which may contain up to 256 individual colors chosen from a palette of more than one million total colors. It is also possible to store Encapsulated PostScript (EPS) code in a WPG file.
The particular version described in this article is the WordPerfect Graphic file format as created by the WPC products WordPerfect 5.x and DrawPerfect 1.x.
A WPG-format file created using WordPerfect 5.0 can store either bitmap or vector image data, but not both at once. WPG files created under WordPerfect 5.1 and later can store both bitmap and vector image data in the same file. Unfortunately, there is no way to tell whether a WPG file contains both bitmap and vector data by reading the header. The actual record data from the body of the file must be read and interpreted.
File Organization
In WPC terminology, a WordPerfect Graphics Metafile contains a prefix area (the header) and a record area (the graphics data). All data in the metafile is written using the big-endian byte order. File Details
This section contains information about the prefix and record areas of a WordPerfect Graphics Metafile. Prefix
The prefix is 16 bytes in length and has the following format:
typedef struct _WordPerfectGraphic { BYTE FileId[4]; /* File Id Code (always FFh 57h 50h 43h) */ DWORD DataOffset; /* Stat of data in the WPG file (always 10h)*/ BYTE ProductType; /* Product Code (always 1) */ BYTE FileType; /* WPC File Code (always 16h) */ BYTE MajorVersion; /* Major Version Code (always 1) */ BYTE MinorVersion; /* Minor Version Code (always 0) */ WORD EncryptionKey;/* Password Checksum (0 = not encrypted) */ WORD Reserved; /* Reserved field (always 0) */ } WPGHEAD;
FileId values are four contiguous bytes that contain the standard WPC File ID code. All WPC files starting with those created by WordPerfect 5.0 begin with this code. The values for these fields, in order, are FFh, 57h, 50h, and 43h.
DataOffset contains an offset value pointing to the start of the record data in the WordPerfect Graphics Metafile. Because the record data always immediately follows the prefix, and the prefix is always 16 bytes in length, this value is always 10h.
ProductType identifies the WPC software product that created the WPG file. This field always contains the value 01h, indicating that the file was created by the WordPerfect word processor. This value is always the same, even if the WPG file was created by a third-party software application.
FileType identifies the type of data the file contains. For WPG files, the value of this field is always 16h.
MajorVersion and MinorVersion contain the internal version number of the product for which the WPG file was created (which may not match the published, external version number of the product). For all WPG files, the MajorVersion field always contains a value of 01h, and the MinorVersion field always contains a value of 00h.
EncryptionKey normally contains a value of 00h if the file is not encrypted. If the value of this field is non-zero, then the value is used as the checksum of the password and is used to decrypt the file. In the current version, WPG files are never encrypted and therefore the value of this field is always 00h.
Reserved is not currently used and always contains a value of 00h. Record Area
Following the prefix in a WordPerfect Graphics Metafile is the record area. This area contains a sequence of objects and their attributes; this information is used to render the image. Any colormaps, bitmaps, and sections of PostScript code are also considered objects within the WPG file record area. Record prefix
Each record begins with a record prefix (a header in almost any other format). The record prefix may be two, four, or six bytes in length depending on the type of record it precedes. Here are the three possible record prefix formats:
/* Two-byte prefix */
typedef struct _TwoByteRecPrefix { BYTE RecordType; /* The Record Type identifier */ BYTE RecordLength; /* The length of the record in bytes (0-FEh)*/ } RECPREFIX2BYTE;
/* Four-byte prefix */
typedef struct _FourByteRecPrefix { BYTE RecordType; /* The Record Type identifier */ BYTE SizeIndicator; /* WORD or DWORD length follows (always FFh)*/ WORD RecordLength; /* The length of the record in bytes */ } RECPREFIX4BYTE;
/* Six-byte prefix */
typedef struct _SixByteRecPrefix { BYTE RecordType; /* The Record Type identifier */ BYTE SizeIndicator; /* WORD or DWORD length follows (always FFh)*/ DWORD RecordLength; /* The length of the record in bytes */ } RECPREFIX6BYTE;
Record type
RecordType, the first field of each record, contains a value that identifies the type of data stored in the record as follows:
Record Type
Record Description
01h
Fill attributes
02h
Line attributes
03h
Marker attributes
04h
Polymarker
05h
Line
06h
Polyline
07h
Rectangle
08h
Polygon
09h
Ellipse
0Ah
Reserved
0Bh
Bitmap (Type 1)
0Ch
Graphics text (Type 1)
0Dh
Graphics text attributes
0Eh
Color map
0Fh
Start of WPG data (Type 1)
10h
End of WPG data
11h
PostScript data follows (Type 1)
12h
Output attributes
13h
Curved polyline
14h
Bitmap (Type 2)
15h
Start figure
16h
Start chart
17h
PlanPerfect data
18h
Graphics text (Type 2)
19h
Start of WPG data (Type 2)
1Ah
Graphics text (Type 3)
1Bh
PostScript data follows (Type 2)
The following is a listing of the record types, their formats, and the flags associated with them. For more information, please consult the Wordperfect documentation. Fill Attributes
BYTE 0
Hollow
1
Solid
2
Finely spaced 45-degree lines
3
Medium spaced 45-degree lines
4
Coarsely spaced 45-degree lines
5
Fine 45-degree hatching
6
Medium 45-degree hatching
7
Coarse 45-degree hatching
8
Fine vertical lines
9
Medium vertical lines
10
Coarse vertical lines
11
Dots density 1 (least dense)
12
Dots density 2
11
Dots density 3
13
Dots density 4
14
Dots density 5
15
Dots density 6
16
Dots density 7 (densest)
18
Dots (medium)
19
Dots (coarse)
20
Fine horizontal
21
Medium horizontal
22
Coarse horizontal
23
Fine 90-degree cross-hatching
24
Medium 90-degree cross-hatching
25
Coarse 90-degree cross-hatching
26
Fine 45-degree lines
27
Medium 45-degree lines
28
Coarse 45-degree lines
29
Brick pattern (horizontal)
30
Brick pattern (vertical)
31
NA
32
Interweaving
33
NA
34
NA
35
Tile pattern
36
Coarse lines (thick)
37
Alternating dark and light squares
BYTE
Fill-color palette index (0-ffh)
Line Attributes
BYTE 0
None
1
Solid
2
Dash 1 (long)
3
Dots
4
Dash-dot
5
Dash 2 (medium)
6
Dash-dot-dot
7
Dash 3 (short)
BYTE
Line color (0-ffh)
WORD
Line width (arbitrary units)
Marker Attributes
BYTE 0
None
1
Dots
2
Plus sign
3
Star
4
Circle
5
Square
6
Triangle
7
Inverted triangle
8
Diamond
9
45-degree cross
BYTE
Marker color (0-ffh)
WORD
Marker height (arbitrary units)
Polymarker
The first area, two bytes in length, holds the number of points. This is followed by a list of WORD coordinate pairs denoting the position of the actual points in arbitrary units. Line
WORD
X value of start of line
WORD
Y value of start of line
WORD
X value of end of line
WORD
Y value of end of line
These are all in arbitrary units. Polyline
The first area, two bytes in length, holds the number of points. This is followed by a list of WORD coordinate pairs denoting the position of the actual points in arbitrary units. Rectangle
WORD
X of lower left of rectangle
WORD
Y of lower left of rectangle
WORD
Width
WORD
Height
These are all in arbitrary units. Polygon
The first area, two bytes in length, holds the number of vertices. This is followed by a list of WORD coordinate pairs denoting the position of the actual vertices in arbitrary units. Ellipse
WORD
X value of center
WORD
Y value of center
WORD
X radius
WORD
Y radius
WORD
Rotation angle measured from the x axis
WORD
Start of arc (degrees)
WORD
End of arc (degrees)
WORD
Flags: bit 0 connect ends of arc to center, bit 1 connect to each other
Bitmap Type 1
WORD
Width (pixels)
WORD
Height (pixels)
WORD
Bits-per-pixel (1,2,4,8)
WORD
X-resolution of source (pixels/inch)
WORD
Y-resolution of source (pixels/inch)
This is followed by the bitmap data in BYTE format. Note that this may be RLE compressed. Graphic Text Type 1
WORD
Text length in bytes
WORD
X value of text position
WORD
Y value of text position
This is followed by the text string in BYTE format. Graphics Text Attributes
WORD
Font character width (arbitrary units)
WORD
Font character height (arbitrary units)
WORD
Reserved
WORD
Reserved
WORD
Reserved
WORD
Reserved
WORD
Reserved
WORD
Font type--e.g., 0df0 Courier, 1150 Helvetica, 1950 Times
BYTE
Reserved
BYTE
Alignment, vertical (0 left, 1 center, 2 right)
BYTE
Alignment, horizontal (0 base, 1 center, 2 cap, 3 bottom, 4 top)
BYTE
Color (0-ffh)
WORD
Rotation (degrees from horizontal)
Colormap
WORD
Start color (0-ffh)
WORD
Number of colors
BYTE
Red value of first color
BYTE
Green value of first color
BYTE
Blue value of first color
.
.
.
BYTE
Red value of last color
BYTE
Green value of last color
BYTE
Blue value of last color
Start of WPG Data
BYTE
Version number
BYTE
Flags (bit 0 PostScript, maybe bitmap, bit 1 PostScript, no bitmap
WORD
Width of image (arbitrary units)
WORD
Height of image (arbitrary units)
End of WPG Data
This record has no data associated with it. It is used to signal the end of a data section in the file and acts as an end-of-file marker. PostScript Data Follows
BYTE
Actual PostScript data
.
.
.
BYTE
Output Attributes (WordPerfect 5.0 only)
BYTE
Background color (0-ffh)
BYTE
Foreground color (0-ffh)
WORD
X value of lower left of clipping window
WORD
Y value of lower left of clipping window
WORD
Clip window width
WORD
Clip window height
Size and position values are in arbitrary units. Curved Polyline (WordPerfect 5.1 and later)
DWORD
Size of equivalent data in pre-5.1 files
WORD
Number of points
WORD
X value of first point
WORD
Y value of first point
WORD
X value of first control point
WORD
Y value of first control point
.
.
.
WORD
X value of last point
WORD
Y value of last point
WORD
X value of last control point
WORD
Y value of last control point
Bitmap Type 2 (WordPerfect 5.1 and later)
WORD
Rotation angle from horizontal (degrees)
WORD
X value of lower left
WORD
Y value of lower left
WORD
X value of upper right
WORD
Y value of upper right
WORD
Width (pixels)
WORD
Height (pixels)
WORD
Pixel depth (bits)
WORD
Horizontal resolution (pixels/inch)
WORD
Vertical resolution (pixels/inch)
This is followed by the actual bitmap data, which is RLE compressed, although there appear to be some (possibly illegal) variants produced by third-party programs which are not. Start Figure
DWORD
Length of object data
WORD
Rotation angle from horizontal (degrees)
WORD
X value of lower left
WORD
Y value of lower left
WORD
X value of upper right
WORD
Y value of upper right
This is followed by the figure data. Start Chart
DWORD
Length of chart data in file
WORD
X value lower left
WORD
Y value lower left
WORD
X value upper right
WORD
Y value upper right
This is followed by the actual chart data. PlanPerfect Data
This is data associated with WordPerfect Corporation's PlanPerfect application. Please contact WordPerfect for more information. Graphics Text Type 2 (WordPerfect version 5.1 and later)
DWORD
Size of equivalent data written by version prior to 5.1
WORD
Rotation angle from horizontal (degrees)
WORD
Length of text (characters)
WORD
X value of text start
WORD
Y value of text start
WORD
X value of text end
WORD
Y value of text end
WORD
X scale factor
WORD
Y scale factor
BYTE
Type (0 window, 1 line, 2 bullet chart, 3 simple chart, 4 free-format chart)
This is followed by the string data. Start of WPG Data Type 2
BYTE
Type
WORD
Length of data in file
This is followed by the actual data. RecordLength
RecordLength, the second field of each record, may be a BYTE, WORD, or DWORD in size, depending upon the value stored in the first BYTE of this field (SizeIndicator above). Because it is possible for the same RecordType to have a different size each time it appears in the same WPG file, each record cannot be assigned a RecordType field of a fixed size. You must therefore determine the size of the RecordLength field when you read the record prefix.
If the BYTE value read after the RecordType field is in the range of 00h to FEh, the RecordLength field is a BYTE in size, and this value is used as the number of bytes in the record. If the BYTE is the value FFh, then the RecordLength field is either a WORD or a DWORD in size.
The next WORD of the prefix is then read. If the high bit of this WORD is 0, then this value is the length of the record. If the high bit is 1, then this value is the upper WORD value of a DWORD length value. The next WORD is read and is used as the lower WORD value in the DWORD. This DWORD value is then the length of the record. The following code should help to clarify this logic:
BYTE RecordType; DWORD RecordLength; FILE *fp; RecordType = GetByte(fp); /* Read the RecordType */ RecordLength = GetByte(fp); /* Read the RecordLength */ if (RecordLength == 0xFF) /* Not a BYTE value */ { RecordLength = GetWord(fp); /* Read the next WORD value */ if(RecordLength & 0x8000) /* Not a WORD value */ { RecordLength <<= 16; /* Shift value into the high WORD */ RecordLength += GetWord(fp); /* Read the low WORD value */ } }
Example Records
The following is a description of several of the records found in the WPG format. For a complete listing of all records and values, refer to the WordPerfect Developer's Toolkit.
The first record of a WPG file is always the Start WPG Data (0Fh) record. This record contains information on the size of the image and the version number of the WPG file and has the following format:
typedef struct _StartWpgRecord { BYTE Version; /* WPG Version Flags (always 01h) */ BYTE WpgFlags; /* Bit flags */ WORD Width; /* Width of image in WP Units */ WORD Height; /* Height of image in WP Units */ } STARTWPGREC;
Version indicates the WPG file version. This value is currently defined to be 01h.
The eight bits in the WpgFlags field are used as flag values. If Bit 0 is set to 0, then there is no PostScript code included in this WPG file. If Bit 0 is set to 1, then PostScipt code is included in this file. Bits 1 through 7 are reserved and always set to 0.
Width and Height contain the size of the image in WP Units (WPU), each of which is equal to 1/1200th of an inch.
A ColorMapRecord (0Eh) normally follows the StartWpgRecord, unless the image is black and white. If no ColorMapRecord is present, then the default colormap is used instead. There is only one ColorMapRecord per WPG file, regardless of how many bitmap or vector objects the file contains. The current WPG format does not provide a way to assign separate colormaps to specific vector objects and bitmaps.
All images stored in a WPG file, both bitmap and vector, use index values into the colormap to define their colors. This record may define an entire color map unique to this image, or it may define only a smaller colormap used to overlay a portion of the default colormap. To avoid problems with WPC products, the first 16 colors in the colormap should never be changed from their default values. The ColorMapRecord has the following format:
typedef struct _ColorMapRecord { WORD StartIndex; /* The starting index of this color map */ WORD NumberOfEntries;/* The number of entries in this color map*/ BYTE *ColorMap[][3]; /* Color map triples */ } COLORMAPREC;
StartIndex indicates the starting color index number of this map.
NumberOfEntries indicates the number of contiguous entries in the colormap from the starting index. If entries 178 though 244 in the default colormap were being replaced by this colormap, the value of StartIndex would be 178, and the value of NumberOfEntries would be 66. If the entire colormap were being replaced, the values of these fields would be 0 and 256 respectively.
These two fields are followed by a sequence of three-byte triples, which hold the actual colormap data. The number of triples is equal to the value stored in the NumberOfEntries field. The number of bytes in this field is calculated by multiplying the value of the NumberOfEntries field by 3. The default colormap for WPG files is the same as the IBM VGA standard color table defined in the PS/2 Display Adapter manual.
The VGA colormap structure is also shown in Chapter 2, in the section called "Examples of Palettes."
This colormap contains 256 color entries, each with a 1-byte red, green, and blue color value for a total of 768 map elements. The first 16 colors are those of the IBM EGA color table. Colors 17 through 32 are 16 gray-scale shades. The remaining 224 colors are a palette of 24 individual colors, each with three different intensity levels and three different saturation levels. The WPG color map uses eight bits for red and six bits each for green and blue.
When displaying WPG images using a display adapter, such as the VGA, with fewer bits per primary color, the color values are truncated starting with the least significant bits. For a VGA adapter that has only 6 bits for red, all 8-bit red values in the color table are shifted to the right twice before the value is used. The green and blue values are not changed.
As previously mentioned, a WPG file created with WordPerfect 5.0 can store either bitmap or vector image data, but not both. This is due to a limitation of the Bitmap (0Bh) record structure. This record is now considered obsolete and should not be used when you create new WPG files. The structure of this record is as follows:
typedef struct _BitmapType1 { WORD Width; /* Width of image in pixels */ WORD Height; /* Height of image in pixels */ WORD Depth; /* Number of bits per pixel */ WORD HorzRes; /* Horizontal resolution of image */ WORD VertRes; /* Vertical resolution of image */ } BITMAP1REC;
Width and Height describe the size of the bitmap in pixels.
Depth contains the number of bits per pixel. The possible values of this field are 1, 2, 4, or 8 for 2-, 4-, 16-, and 256-color images.
HorzRes and VertRes are the horizontal and vertical resolution of the original bitmap in pixels per inch. These values can also describe the minimum resolution of the screen required to display the image.
The bitmap data follows this record structure. The Bitmap Type 1(0Bh) record was superseded by the Bitmap Type 2 (14h) record introduced with WordPerfect 5.1. This new record added five fields not found in the Bitmap Type 1 record. These fields contain information on the position of the bitmap on the output device. If you use a Bitmap Type 2 record, it is also possible to store multiple bitmaps in a single WPG file.
The structure of the Bitmap Type 2 record is shown below:
typedef struct _BitmapType2 { WORD RotAngle; /* Rotation angle of bitmap (0-359) */ WORD LowerLeftX; /* Lower-left X coordinate of image */ WORD LowerLeftY; /* Lower-left Y coordinate of image */ WORD UpperRightX; /* Upper-right X coordinate of image */ WORD UpperRightY; /* Upper-right Y coordinate of image */ WORD Width; /* Width of image in pixels */ WORD Height; /* Height of image in pixels */ WORD Depth; /* Number of bits per pixel */ WORD HorzRes; /* Horizontal resolution of image */ WORD VertRes; /* Vertical resolution of image */ } BITMAP2REC;
RotAngle is the rotation angle of the bitmap in degrees. This value may be in the range of 0 to 359, with 0 indicating the image is not rotated.
LowerLeftX and LowerLeftY describe the location of the lower-left corner of the image in WPUs.
UpperRightX and UpperRightY describe the location of the upper-right corner of the image in WPUs. Note that the origin point (0,0) of all WPG images is the lower left-hand corner of the output device.
The remaining five fields, Width, Height, Depth, HorzRes, and VertRes, are identical to those in the Bitmap Type 1 record.
It is possible to store two or more images in a WPG file by using multiple Bitmap records. The coordinate information found in a Bitmap Type 2 record will allow the images to be positioned on the output device so they do not overlap. The size of a bitmap in bytes may be determined by multiplying the Height, Width, and Depth fields and then dividing the product by 8:
SizeInBytes = (Height * Width * Depth) / 8;
Bitmap data is always stored in a WPG file using a byte-wise run-length encoding (RLE) algorithm. (See Chapter 9, Data Compression, for more information on run-length encoding algorithms.) Each scan line is encoded separately.
There are four possible types of RLE packets in the WPG algorithm:
* Encoded packet
* Literal packet
* All-bits-on packet
* Repeat scan-line packet
An encoded packet may encode a run of from 1 to 127 bytes in length. An encoded packet always has the most significant bit (MSB) as 1 and the seven least significant bits (LSBs) are a non-zero value. The length of the run is the value of the seven LSBs. If the MSB of this byte is 1, but the seven LSBs are set to 0, then the next byte is read as the run count and the byte value FFh is repeated "run count" times. If the MSB of the byte read is 0, and the seven LSBs are a non-zero value, then this is a literal run. The seven LSBs hold the run-count value and the next "run count" bytes are read literally from the encoded data stream. If the run count is 0, then the next byte is read as the run count and the previous scan line is repeated "run count" times.
The pseudocode for the WPG RLE algorithm is shown below:
Read a BYTE If the Most Significant Bit is ON If the 7 LSB are not 0 The RunCount is the 7 least significant bits Read the next BYTE and repeat it RunCount times If the 7 LSB are 0 Read the next BYTE as the RunCount Repeat the value FFh RunCount times If the Most Significant Bit is OFF If the 7 LSB are not 0 The RunCount is the 7 least significant bits The next RunCount BYTEs are read literally If the 7 LSB are 0 Read the next BYTE as the RunCount Repeat the previous scan line RunCount times
Encapsulated PostScript (EPS) data may be included in a WPG file by using the PostScript Data Type 1 (11h) record or the PostScript Data Type 2 (1Bh) record. The PostScript Data Type 1 record contains a set of output commands needed to print the EPS code included in the WPG file on a PostScript printer. The structure for the PostScript Data Type 1 record is as follows:
typedef struct _PsDataType1 { WORD BbLowerLeftX; /* Lower left X coordinate of image */ WORD BbLowerLeftY; /* Lower left Y coordinate of image */ WORD BbUpperRightX; /* Upper right X coordinate of image */ WORD BbUpperRightY; /* Upper right Y coordinate of image */ } PSTYPE1REC;
The four fields in this record contain the bounding-box values of the PostScript image in points. These are the values found in the %%BoundingBox field in the EPS header. The EPS data immediately follows this record. The PostScript Data Type 2 record is used to store one or more EPS images. If the EPS data also contains a TIFF, PICT, WMF, or EPSI image, as is found in a Display PostScript file, this data is converted to a Bitmap Type 2 record that follows the PostScript Data Type 2 record.
The structure for the PostScript Data Type 2 record is shown below:
typedef struct _PsDataType2 { DWORD RecordLength; /* Length of the following record */ WORD RotAngle; /* Angle of roation of image */ WORD LowerLeftX; /* Lower-left X coordinate of image */ WORD LowerLeftY; /* Lower-left Y coordinate of image */ WORD UpperRightX; /* Upper-right X coordinate of image */ WORD UpperRightY; /* Upper-right Y coordinate of image */ BYTE FileName[40]; /* File name of original EPSF file */ WORD BbLowerLeftX; /* Lower-left X coordinate of bounding box */ WORD BbLowerLeftY; /* Lower-left Y coordinate of bounding box */ WORD BbUpperRightX; /* Upper-right X coordinate of bounding box */ WORD BbUpperRightY; /* Upper-right Y coordinate of bounding box */ } PSTYPE2REC;
RecordLength indicates the number of bytes occuring in the Bitmap Type 2 record following the EPS data. If the EPS data does not have an associated Bitmap Type 2 record, then the value of this field is 0.
The RotAngle, LowerLeftX, LowerLeftY, UpperRightX, and UpperRightY fields have the same meaning as in the Bitmap Type 2 (14h) record.
FileName contains the name of the original EPSF file from which this EPSF code was derived.
The BbLowerLeftX, BbLowerLeftY, BbUpperRightX, and BbUpperRightY fields are the same as in the PostScript Data Type 1 (11h) record.
The EPSF code immediately follows this record. The PostScript Data Type 2 record found in WordPerfect 5.1 and DrawPerfect supersedes the PostScript Data Type 1 record found only in WordPerfect 5.0 and DrawPerfect 1.0. You should always use the Type 2 record rather than the Type 1 when creating new WPG files.
The last record in every WPG file is the End of WPG Data (10h) record. This record has a NULL body; it merely marks the end of the WPG record stream.
This page is taken from the Encyclopedia of Graphics File Formats and is licensed by O'Reilly under the Creative Common/Attribution license.