The PCX Format is an image format used by many games, usually to store full screen (320x200) 16-colour EGA, and later 256-colour VGA (mode 13h), graphics. It was, for a time, also a general picture format like .bmp or .png, and was the primary format used by PC Paintbrush. It declined in popularity after support for 24-bit true colour images was added too late, by which time many people had switched to competing formats like .png and JPEG (the latter offering far better compression for photos.) It also lacks support for transparency, which resulted in it losing some ground to the GIF format which otherwise provided a similar feature set.

Number of bytes to read for a single plane's scanline, i.e. at least image_width ÷ 8 bits per byte × bitsPerPlane. MUST be an EVEN number. Do NOT calculate from Xmax-Xmin. Normally a multiple of the machine's native word length (2 or 4)

Image Data

Image data comes after the header (starting at offset 0x80 in a PCX file.) The way the data is stored depends on how many colour planes are specified. Each row has its color planes stored sequentially, similar to raw EGA data.

For one plane of eight bits (256-colour), each byte will represent one pixel. For one plane of four bits (16-colour), each byte will represent two pixels. The bits within the byte are in big-endian order, so the most significant bit belongs to the left-most pixel. In other words, a byte of value 0xE4 (binary 11 10 01 00) will have left-to-right pixel values of 3, 2, 1, 0, assuming two bits per pixel.

EGA 16-colour images are often stored with four colour planes instead of one, with each plane being one-bit-per-pixel (think of four black and white images, one each for red, green, blue and intensity.) The planes are stored sequentially for each line (see Row-planar EGA data for the exact details), thus a 320x200 EGA image will store at least 40 bytes for each scanline's colour plane (320 pixels ÷ 8 bits per byte × 1 bit per pixel), with each scanline being at least 160 bytes long (320 pixels ÷ 8 bits per byte × 1 bit per pixel × 4 planes). Note that the scanline length can be larger than expected (40 bytes in this example), especially for images whose width is not a multiple of four. This is because each scanline in a plane is padded to a multiple of two or four bytes, depending on the architecture of the machine used to create the file. The actual size is stored in the bytesPerPlaneLine field in the header, which should always be used instead of calculating the value from the other image attributes.

True colour PCX files are not common, and could be either three planes (R, G and B) of eight bits each (24-bit RGB) or one plane of 24-bits.

The split into planes is generally governed by what is most convenient for the game at the time, which in turn depends on which video mode is being used to display the image. Since EGA video memory is split into planes, 16-colour PCX files are frequently split into matching planes so that no processing is required when loading an image directly into video memory.

RLE Compression

The PCX format uses a form of RLE Compression that is rather unique. It compresses on the byte level and uses a flag system, where the flag is the two highest bits of a byte. If this flag is set (i.e. the two upper bits are set, or in other words the value is >= 192) then the lower six bits are the number of times to repeat the following byte.

Thus the byte pair $C7 $28 means '7 bytes of $28' (the flag value is 192 (128 + 64) so $C7 is 199-192 or a length of 7 bytes, or alternatively using faster logic operations, byte & 0x3F will yield the length value).

This means that the six-bit length values have a maximum of 63. It also means that any value larger than 191 MUST be stored as a length/value pair, which can actually INCREASE the size of the file in some cases. For instance, if you have a single byte of color 192, then it must be represented by two bytes - one of 193 ($C1, length byte of 1) followed by one of 192 ($C0, color byte 192).

It is also worth noting that this scheme results in the redundant encoding $C0, which means 'repeat the following byte zero times', effectively ignoring any byte following $C0. This could conceivably be used to embed non-image data in the PCX file which would be ignored by any program displaying the image.

Note that compression (at least for EGA four plane images) usually applied not for whole image, but for each line separately. For example, if your input image 8x4 pixels EGA 16 colour where the first two lines of pixels are black (color 0) and the last two are white (color 15), they must be compressed as $C4 $00 | $C4 $00 | $C4 $FF | $C4 $FF and not as $C8 $00 | $C8 $FF.

Palette

For images with 16 colours or less, the palette is stored in the header. For images with more colours (i.e. 256-colour images) the header palette is ignored, and the 768-byte VGA Palette (in 8-bit RGB format) is stored after the image data. A single signature byte of 0x0C is included before the palette data begins.