31 Looking to add monochrome or full-color bit-mapped graphics to your
\r
32 application programs? If so, you might consider the PCX graphics file
\r
33 format. Originally developed in 1982 by ZSoft Corporation for their PC
\r
34 Paintbrush (R) products, it has become a de facto industry standard for
\r
35 storing and transferring bit-mapped images on MS-DOS machines. It can
\r
36 support displays of any resolution using palettes of up to 256
\r
37 simultaneous colors, and is very simple to implement. Furthermore, it's
\r
38 not limited to MS-DOS and OS/2-based machines; the PCX format is
\r
39 applicable to any environment supporting bit-mapped graphics.
\r
41 Today, more commercial programs support ZSoft's PCX format than any
\r
42 other, including Aldus-Microsoft's Tag Image File Format (TIFF).
\r
43 However, unlike TIFF with its publicly-available technical
\r
44 specifications, the PCX file format has never been completely documented.
\r
45 When ZSoft first created PC Paintbrush, the only video displays they had
\r
46 to contend with were two monochrome adapters (Hercules and Tecmar) and
\r
47 the IBM Color Graphics Adapter (CGA). They have since quietly modified
\r
48 and extended their format on several occasions to support EGA, VGA and
\r
49 SuperVGA displays. Documentation is scarce, incomplete and sometimes
\r
50 contradictory. There's a small booklet available from ZSoft that
\r
51 describes the current version (with several omissions), a sample Pascal
\r
52 program from their CompuServe forum (GO WINAPB), a few magazine articles,
\r
53 and chapters in a few books (see the references at the end of this
\r
56 Personally, I think it's about time to remedy this situation. The
\r
57 following is a complete set of technical specifications for the current
\r
58 version of PCX. All of the information has been derived from printed
\r
59 information provided by ZSoft and conversations with their Technical
\r
60 Services department. This is it, folks! We now have formal (if not
\r
61 exactly official) specifications to work with when including the PCX
\r
62 graphics file format in our application programs.
\r
64 My original plan was to include sample C source code for reading and
\r
65 writing PCX image files. However, both this article and the source code
\r
66 grew to the extent that one had to go. If you don't want to develop your
\r
67 own PCX file handling routines from scratch, PCX_LIB is available through
\r
68 the CUG Library as CUG Volume #???. It includes fully commented C source
\r
69 code for reading and writing PCX image files, complete with software
\r
70 drivers for Hercules, CGA, EGA, and VGA display adapters.
\r
94 The PCX graphics file format (Version 5) is designed to store monochrome
\r
95 and color bit-mapped images of any resolution with palettes of up to 256
\r
96 simultaneous colors. It was originally designed for MS-DOS
\r
97 microcomputers, but is adaptable to other bit-mapped graphic
\r
98 environments. A simple but effective byte-oriented, run-length encoding
\r
99 scheme is used to compress the image data.
\r
101 There are two or three sections to a PCX graphics file - a 128-byte
\r
102 header, the encoded image data (which can be of any length) and an
\r
103 optional 256-color palette (see Figure 1). This palette is appended to
\r
104 the file only if the image contains more than 16 colors.
\r
155 The file header describes the graphical environment in which the image is
\r
156 to be displayed. The information contained in the header is somewhat
\r
157 device-dependent in that the PCX file format implicitly assumes the
\r
158 presence of a standard IBM PC-compatible display adapter. Furthermore,
\r
159 the specific type and video mode of the adapter needed to display the
\r
160 image correctly cannot be uniquely determined from the file header
\r
161 information. It is in general the user's responsibility to ensure that
\r
162 the correct video mode has been selected before displaying a PCX image.
\r
164 The file header structure is shown in Figure 2. A complete description
\r
165 of each structure member is as follows:
\r
169 A constant value (0x0a) that signifies a PCX image file.
\r
173 Indicates the PCX file format version. It can be one of five values:
\r
175 0 - Version 2.5 of PC Paintbrush.
\r
176 2 - Version 2.8 (with palette information).
\r
177 3 - Version 2.8 (without palette information).
\r
178 4 - PC Paintbrush for Windows (not 3.0).
\r
179 5 - Version 3.0 and greater of PC Paintbrush and Paintbrush Plus,
\r
180 including Publisher's Paintbrush.
\r
182 Most commercial programs supporting the PCX file format conform to
\r
183 Version 5. See Section 3, "Color Palettes", for further information.
\r
187 A constant value (0x01) that indicates run-length encoding was used to
\r
188 encode and compress the image data.
\r
192 The number of bits per pixel per color plane (typically 1, 2, 4 or 8).
\r
196 A structure with the following members:
\r
198 Name Bytes Description
\r
200 xul 2 Upper left corner horizontal position
\r
201 yul 2 Upper left corner vertical position
\r
202 xlr 2 Lower right corner horizontal position
\r
203 ylr 2 Lower right corner vertical position
\r
205 These members describe the position and size of the image within the
\r
206 display, and are measured in pixels (starting with zero).
\r
216 "Horizontal dots per inch". The value represents the horizontal
\r
217 resolution of the device used to create the image.
\r
221 "Vertical dots per inch". The value represents the vertical resolution
\r
222 of the device used to create the image.
\r
226 The color palette to be used when displaying an image with 16 or fewer
\r
227 colors. See Section 3, "Color Palettes", for further information.
\r
231 This member was used to indicate the appropriate MS-DOS video mode in
\r
232 previous PCX file format versions. It is ignored in Version 5, but
\r
233 should be set to zero.
\r
237 The number of color planes used to display the image (typically 1 or 4).
\r
238 See Section 3, "Color Palettes", for further information.
\r
240 1.11 Bytes per Line
\r
242 The number of bytes required for a buffer when decoding one color plane
\r
243 scan line. This value should be an even number (for compatibility with
\r
244 some existing commercial programs). See Section 2, "Image Encoding and
\r
245 Decoding", for further information.
\r
247 1.12 Palette Info (3)
\r
249 A bit-mapped variable indicating how to interpret the color palette.
\r
250 Only the lowest two bits are significant; the others are ignored. It
\r
251 can have one of two possible values:
\r
253 0x01 - color or black & white
\r
256 If the variable is set to 0x02 (grayscale), the color palette must be set
\r
257 to shades of gray.
\r
259 1.13 HScreen Size (4)
\r
261 Horizontal screen size in pixels.
\r
263 1.14 VScreen Size (4)
\r
265 Vertical screen size in pixels.
\r
269 Blank space to fill out 128-byte header. All bytes within this member
\r
270 should be set to zero.
\r
277 1. ZSoft has reserved the right to change the encoding scheme for better
\r
278 image compression performance in future versions.
\r
280 2. Horizontal and vertical resolution for video display adapters is
\r
281 defined as the total number of displayed pixels for the current video
\r
282 mode. For scanners, it is defined in terms of dots per inch. (These
\r
283 values are provided for information only. They are not required for
\r
284 encoding or decoding PCX image files.)
\r
286 3. The "palette info" member of the file header was used in previous
\r
287 versions of the PCX file format to indicate whether the palette
\r
288 represented a color or grayscale palette. If it was set to 0x02 (as a
\r
289 bitmap - the upper 6 bits could be set at random), the file decoding
\r
290 functions could assume a default grayscale palette if necessary.
\r
291 However, the palette already had a true (and possibly nonlinear)
\r
292 grayscale, so the "palette info" member was never really used by
\r
293 ZSoft. The current PC Paintbrush IV and IV Plus products simply
\r
296 4. The "HScreen Size" and "VScreen Size" members were added to Version 5
\r
297 of the PCX format to support PC Paintbrush IV Version 1.02 and IV Plus
\r
298 Version 1.0. Since earlier Version 5 PCX files may contain
\r
299 uninitialized data in place of these members, ZSoft specifically
\r
300 recommends that they not be used to determine the appropriate video
\r
301 mode for displaying the files.
\r
336 2. Image Encoding and Decoding
\r
338 The PCX graphics file format considers an image to be a contiguous
\r
339 sequence (block) of eight-bit bytes representing a bit-mapped raster
\r
340 display. A simple byte-oriented, run-length encoding (RLE) scheme is
\r
341 used to compress the display data. When the display is represented by
\r
342 more than one color plane (such as color images on EGA displays), each
\r
343 scan line is stored sequentially by color plane.
\r
345 The run-length encoding scheme uses a byte pair consisting of a "count"
\r
346 byte and a following "data" byte to represent sequences of display bytes
\r
347 with the same value. A count byte is uniquely identified by having its
\r
348 two most significant bits set; its six least significant bits are used to
\r
349 represent the count value (1 to 63). The following data byte is the
\r
350 value that is repeated in the display data the number of times indicated
\r
351 by the count value.
\r
353 Any display data byte which is not part of a sequence of bytes of the
\r
354 same value and which does not have its two most significant bits set is
\r
355 stored as itself in the encoded image data. Single display data bytes
\r
356 with a value of 0xc0 or greater are encoded with a count value of one.
\r
360 Decoding display data from encoded image data is done on a line-by-line
\r
361 basis. The pixel dimensions of the displayed image are calculated as:
\r
363 horz_size = Window.xlr - Window.xul + 1
\r
367 vert_size = Window.ylr - Window.yul + 1
\r
369 The number of bytes required to buffer one complete scan line for all
\r
370 color planes in sequence is:
\r
372 buffer_size = NPlanes * Bytes per Line
\r
374 Since there are always an integral number of bytes in the buffer, there
\r
375 may be unused data at the end of each color plane scan line if the number
\r
376 of bits per pixel is other than eight. This unused data should be masked
\r
377 off when transferring the line buffer contents to the video display
\r
380 In theory, each color plane scan line may contain an even or odd number
\r
381 of bytes. However, some application programs expect an even number of
\r
382 bytes. ZSoft ensures that their products create PCX files with an even
\r
383 number of bytes per color plane scan line, and recommends that other
\r
384 programs do the same for compatibility. Of course, decoding functions
\r
385 should be able to read files with either an even or odd number of bytes
\r
386 per color plane scan line.
\r
388 Decoding begins with the first scan line and proceeds by examining each
\r
389 byte of the encoded image data. If the two most significant bits of the
\r
390 byte are set, the lower six bits indicate how many times the next byte is
\r
397 Decoding begins with the first scan line and proceeds by examining each
\r
398 byte of the encoded image data. If the two most significant bits of the
\r
399 byte are set, the lower six bits indicate how many times the next byte is
\r
400 to be duplicated in the line buffer. If these two bits are not set, the
\r
401 byte itself is copied (once) to the line buffer. A count is kept of the
\r
402 number of bytes in the line buffer. The current scan line is complete
\r
403 when its value equals "buffer_size".
\r
405 If the display contains more than one color plane, each plane is decoded
\r
406 in sequence. The order in which they are decoded is device-dependent.
\r
407 For instance, the Enhanced Graphics Adapter has four color planes ordered
\r
408 as blue, green, red and intensity. The beginning of each color plane
\r
409 scan line within the line buffer is given by:
\r
411 offset = plane_number * Bytes per Line
\r
413 where "plane_number" is a number between 0 and NPlanes - 1.
\r
415 A decoding break occurs at the end of each scan line. That is, an
\r
416 encoding byte pair can only represent a contiguous sequence of bytes
\r
417 within the current scan line. However, this is not necessarily true for
\r
418 color planes. An encoding byte pair may represent a contiguous sequence
\r
419 of identical bytes that extends across two color planes for one display
\r
422 Decoding continues until all scan lines (as indicated by "vert_size")
\r
423 have been decoded. Some older versions of PC Paintbrush padded the image
\r
424 with extra (uninitialized) scan lines so that all blocks of scan lines (8
\r
425 or 16 lines) read from the file were the same size. The image data was
\r
426 read until end-of-file was returned. ZSoft no longer uses this
\r
427 technique, since it conflicts with the appended color palette (see
\r
428 Subsection 3.3, "VGA 256-Color Palettes"). The extra data read could
\r
429 also overrun the user's image buffer.
\r
431 A sample C function to decode a complete image scan line (all color planes)
\r
432 from a PCX file is shown in Figure 3.
\r
436 Encoding display image data is also done on a line-by-line basis,
\r
437 following the order of scan lines stored in the display adapter's memory
\r
438 buffer. The current scan line is encoded for each color plane on a per-
\r
439 byte basis. As noted above, ZSoft recommends that all color plane scan
\r
440 lines be padded if necessary to ensure they contain an even number of
\r
443 ZSoft also recommends that the data used to pad the last one or two bytes
\r
444 of a scan line represent white data. Apparently, some application
\r
445 programs display this data when printing or faxing the files.
\r
447 A sample C function to encode a single monochrome or color image scan
\r
448 line for a PCX file is shown in Figure 4.
\r
460 The PCX file format supports color palettes of up to 16 colors in the
\r
461 file header. Larger palettes (up to a maximum of 256 colors) are stored
\r
462 in an optional color palette that is appended to the encoded image data
\r
463 portion of the file.
\r
465 The file header color palette has two different formats, both designed
\r
466 for IBM PC-compatible machines. A device-specific palette is used for
\r
467 Color Graphics Adapters (CGA), and a standard R-G-B palette is used for
\r
468 Enhanced Graphics Adapters (EGA), Multicolor Graphics Adapters (MCGA),
\r
469 Video Graphics Adapters (VGA) and extended Video Graphics Adapters
\r
472 ZSoft's PC Paintbrush products no longer support the CGA color palette.
\r
473 The following information is provided only for compatibility with older
\r
476 3.1. CGA Color Palettes
\r
478 The PCX format supports eight possible CGA color palettes for video modes
\r
479 4 (320x200 4-color graphics) and 5 (320x200 monochrome graphics, color
\r
480 burst off). Each palette consists of a background color and three
\r
481 foreground colors (or shades of grey). The background can be one of 16
\r
482 colors, the value for which is stored in the first byte of the PCX file
\r
483 header Color Map member. Only the upper four bits are significant; the
\r
484 value must be right-shifted by four bits (or divided by 16) to determine
\r
485 the appropriate CGA hardware palette register value.
\r
487 The foreground color palette is specified by the fourth byte of the Color
\r
488 Map, which has the following structure:
\r
490 Name Bit Description
\r
492 Color Burst Enable 7 0 - color
\r
494 Palette 6 0 - yellow
\r
496 Intensity 5 0 - dim
\r
499 The lower five bits are ignored.
\r
501 Most published descriptions of the ROM BIOS call "Set CGA Palette"
\r
502 (Interrupt 16, Function 11) document only two palettes, obtainable by
\r
503 setting register BL to 0x00 or 0x01. This is equivalent to the "Palette"
\r
504 bit above. However, the palette intensity (equivalent to the "Intensity"
\r
505 bit above) can be selected using bit 4 of the BL register (0 = dim, 1 =
\r
508 The original CGA display adapter was designed for use with NTSC composite
\r
509 video monitors and color televisions. The "color burst" is a periodic
\r
510 burst of a 3.58 MHz signal superimposed on the composite video signal to
\r
511 synchronize the phase of the monitor's internal 3.58 MHz oscillator.
\r
512 (Without synchronization, the picture has drifting color bars.) The
\r
513 presence or absence of the burst determines whether the image is
\r
514 displayed in color or monochrome.
\r
519 The "Color Burst Enable" bit above actually indicates whether the MS-DOS
\r
520 video mode is to be 4 (color) or 5 (monochrome). However, the color
\r
521 burst signal has no meaning for RGB monitors. Video mode 5 will produce
\r
522 only two distinct color palettes on CGA displays adapters with RGB
\r
523 monitors, and three distinct palettes on EGA, VGA and SuperVGA display
\r
524 adapters emulating a CGA display.
\r
526 Under video mode 6 (640 x 200 2-color graphics), the first byte of the
\r
527 CGA color palette specifies the foreground color (i.e. - the color of
\r
528 the displayed pixels).
\r
530 3.2. EGA/VGA 16-Color Palettes
\r
532 The 16-color palette for EGA, MCGA, VGA and SuperVGA displays is an array
\r
533 of 16 elements, each a structure with the following members:
\r
535 Name Bytes Description
\r
537 Red 1 Red intensity
\r
538 Green 1 Green intensity
\r
539 Blue 1 Blue intensity
\r
541 All color map entries are stored as unsigned bytes with values ranging
\r
542 between 0 and 255. Where display adapters support fewer intensity
\r
543 levels, the value of each color map entry is interpreted by dividing its
\r
544 value by 256/n, where n is the number of allowable intensity levels
\r
545 (typically 2, 4 or 16).
\r
547 3.3. VGA 256-Color Palettes
\r
549 The 256-color palette for MCGA, VGA and SuperVGA displays is an array of
\r
550 256 elements, each a structure with the same members as the EGA/VGA 16-
\r
551 color palette, which is appended to the encoded image data portion of the
\r
552 file (see Figure 1). It is always preceded by a constant byte flag with
\r
553 the value 0x0c (12 decimal).
\r
555 Only Version 5 PCX-format files support 256-color palettes, and then only
\r
556 when the image has more than 16 colors. ZSoft recommends the following
\r
557 technique to determine if a 256-color palette is present: first verify
\r
558 that the file version number is 5, then count back 769 bytes from the end
\r
559 of the file. If the value of this byte is not 0x0c, the optional 256-
\r
560 color palette is not present and the EGA/VGA 16-color file header palette
\r
563 It is possible that a Version 5 PCX-format file with a valid file header
\r
564 palette can have the value 0x0c in the 769th byte from the end of the
\r
565 encoded image data. The above technique would then falsely indicate the
\r
566 presence of an appended 256-color palette. To avoid this problem, it is
\r
567 necessary to first decode the image and note the file position where the
\r
568 encoded image data section ends before counting back 769 bytes from the
\r
569 end of the file. If the supposed 256-color palette flag is located in
\r
570 the image data section, then the file header palette should be used
\r
582 Future versions of ZSoft's Publisher's Paintbrush will support up to 16.7
\r
583 million simultaneous colors. The PCX file format will be based on three
\r
584 color planes (red, green and blue), with 8 bits per pixel per plane.
\r
585 There will be no color palette, since the color of each pixel will be
\r
586 fully specified by the encoded image data.
\r
588 3.5. Disabling the Palette
\r
590 It is occasionally necessary to disable the color palette of a PCX file
\r
591 in order to correctly display the image. In other words, the current
\r
592 (default) setting of the display adapter's palette registers are used.
\r
593 This can be done by changing the PCX file version number from '5' to '3'
\r
594 (i.e. - PC Paintbrush Version 2.8 without palette information). The file
\r
595 decoding functions must then check the file version number and ignore the
\r
596 color palette if it is set to '3'.
\r
637 4. Other Environments
\r
639 While the PCX file format was designed for MS-DOS machines, it is
\r
640 nevertheless possible to display PCX images on other machines. It will
\r
641 generally be necessary to map the image representation (i.e. - window
\r
642 dimensions, number of color planes, bits per pixel per plane, and the
\r
643 color palette) to the capabilities of the display hardware.
\r
645 It is also necessary to remember that all information in a PCX-format
\r
646 file is stored as either 8-bit bytes or 16-bit words. Words are stored
\r
647 in the big-endian format characteristic of 80x86-based machines. That
\r
648 is, the eight least significant bits (lower byte) are stored first,
\r
649 followed by the eight most significant bits (upper byte). If PCX-format
\r
650 files are transferred to little-endian machines (such as those based on
\r
651 680x0 and Z8000 processors), the order of bytes within each word will
\r
652 have to be reversed before they can be interpreted. (This applies to the
\r
653 file header only, since the encoded image data and optional 256-color
\r
654 palette are stored as bytes.)
\r
700 Azer, S. [1988]. "Working With PCX Files", Microcornucopia, No. 42
\r
701 (July-August), p. 42.
\r
703 Lindley, C.A. [1990]. Practical Image Processing in C, John Wiley & Sons
\r
704 Inc., New York, N.Y.
\r
706 Luze, M. [1991]. "Printing PCX Files", C Gazette, Vol. 5:2 (Winter 1990 -
\r
709 Phoenix Technologies Ltd. [1989]. System BIOS for IBM PC/XT/AT Computers
\r
710 and Compatibles, Addison-Wesley, Reading, MA.
\r
712 Quirk, K. [1989]. "Translating PCX Files", Dr. Dobb's Journal, Vol. 14:8
\r
713 (August), pp. 30-36, 105-108.
\r
715 Rimmer, S. [1990]. Bit-Mapped Graphics, Windcrest Books, Blue Ridge
\r
718 ZSoft Corporation [1988]. PCX Technical Reference Manual Revision 4,
\r
719 ZSoft Corporation, Marietta, GA.
\r
761 +--------------------------------------------+
\r
762 | File Header (128 bytes) |
\r
763 +--------------------------------------------+
\r
764 | Encoded Image Data (variable length) |
\r
765 +--------------------------------------------+
\r
766 | Optional Color Palette (769 bytes) |
\r
767 +--------------------------------------------+
\r
769 Figure 1 - Basic PCX File Format
\r
772 Name Bytes Description
\r
774 PCX Flag 1 Constant flag
\r
775 Version 1 PCX version number
\r
776 Encoding 1 Run-length encoding flag
\r
777 Bits per Pixel 1 Number of bits per pixel per plane
\r
778 Window 8 Window dimensions
\r
779 HDPI 2 Horizontal image resolution
\r
780 VDPI 2 Vertical image resolution
\r
781 Color Map 48 Hardware R-G-B color palette
\r
782 Reserved 1 (Used to contain video mode)
\r
783 NPlanes 1 Number of color planes
\r
784 Bytes per Line 2 Number of bytes per scan line
\r
785 Palette Info 2 Palette interpretation
\r
786 HScreen Size 2 Horizontal screen size
\r
787 VScreen Size 2 Vertical screen size
\r
788 Filler 54 Initialized filler bytes
\r
790 Figure 2 - PCX File Header Structure
\r
793 /* Read an encoded scan line (all color planes) from a */
\r
794 /* PCX-format image file and write the decoded data to a scan */
\r
799 unsigned char *linep, /* PCX scan line buffer pointer */
\r
800 FILE *fp, /* PCX image file pointer */
\r
801 int bpline /* # bytes per line (all color planes) */
\r
804 int data; /* Image data byte */
\r
805 int count; /* Image data byte repeat count */
\r
806 int offset = 0; /* Scan line buffer offset */
\r
808 while (offset < bpline) /* Decode current scan line */
\r
810 data = getc(fp); /* Get next byte */
\r
812 /* If top two bits of byte are set, lower six bits show how */
\r
813 /* many times to duplicate next byte */
\r
820 if ((data & 0xc0) == 0xc0)
\r
822 count = data & 0x3f; /* Mask off repeat count */
\r
823 data = getc(fp); /* Get next byte */
\r
824 memset(linep, data, count); /* Duplicate byte */
\r
830 *linep++ = (unsigned char) data; /* Copy byte */
\r
836 Figure 3 - Decode PCX Image File Scan Line Function
\r
839 /* Encode a scan line and write it to a PCX file (the line is */
\r
840 /* assumed to contain the color plane scan lines in sequence, */
\r
841 /* with padding for an even number of bytes and trailing white */
\r
842 /* data for each line as appropriate) */
\r
844 void pcx_write_line
\r
846 unsigned char *linep, /* Scan line buffer pointer */
\r
847 int length, /* Scan line buffer length (in bytes) */
\r
848 FILE *fp /* PCX file pointer */
\r
851 int curr_data; /* Current data byte */
\r
852 int prev_data; /* Previous data byte */
\r
853 int data_count; /* Data repeat count */
\r
854 int line_count; /* Scan line byte count */
\r
856 prev_data = *linep++; /* Initialize the previous data byte */
\r
860 while (line_count < length) /* Encode scan line */
\r
862 curr_data = *linep++; /* Get the current data byte */
\r
863 line_count++; /* Increment line byte count */
\r
865 if (curr_data == prev_data) /* Repeating data bytes ? */
\r
867 data_count++; /* Increment data repeat count */
\r
869 if (data_count == 0x3f) /* Max allowable repeat count ? */
\r
871 pcx_encode(prev_data, data_count, fp); /* Encode data */
\r
881 else /* End of repeating data bytes */
\r
883 if (data_count > 0)
\r
884 pcx_encode(prev_data, data_count, fp); /* Encode data */
\r
886 prev_data = curr_data; /* Current data byte now prev */
\r
891 if (data_count > 0) /* Any remaining data ? */
\r
893 pcx_encode(prev_data, data_count, fp); /* Encode data */
\r
898 /* Write an encoded byte pair (or single byte) to a file */
\r
902 int data, /* Data byte */
\r
903 int count, /* Data byte repeat count */
\r
904 FILE *fp /* PCX file pointer */
\r
907 if (((data & 0xc0) == 0xc0) || count > 1)
\r
909 putc(0xc0 | count, fp); /* Write count byte */
\r
912 putc(data, fp); /* Write data byte */
\r
915 Figure 4 - Encode Image Scan Line Functions
\r