--- /dev/null
+\r
+\r
+Ian Ashdown\r
+byHeart Software\r
+620 Ballantree Road\r
+West Vancouver, B.C.\r
+Canada V7S 1W3\r
+\r
+Issue 1: 91/02/12\r
+Issue 2: 91/03/27\r
+Issue 3: 91/08/08\r
+Issue 4: 91/08/11\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+ PCX Graphics\r
+\r
+ by \r
+\r
+ Ian Ashdown\r
+ byHeart Software\r
+\f\r
+Looking to add monochrome or full-color bit-mapped graphics to your \r
+application programs? If so, you might consider the PCX graphics file \r
+format. Originally developed in 1982 by ZSoft Corporation for their PC \r
+Paintbrush (R) products, it has become a de facto industry standard for \r
+storing and transferring bit-mapped images on MS-DOS machines. It can \r
+support displays of any resolution using palettes of up to 256 \r
+simultaneous colors, and is very simple to implement. Furthermore, it's \r
+not limited to MS-DOS and OS/2-based machines; the PCX format is \r
+applicable to any environment supporting bit-mapped graphics. \r
+\r
+Today, more commercial programs support ZSoft's PCX format than any \r
+other, including Aldus-Microsoft's Tag Image File Format (TIFF). \r
+However, unlike TIFF with its publicly-available technical \r
+specifications, the PCX file format has never been completely documented. \r
+When ZSoft first created PC Paintbrush, the only video displays they had \r
+to contend with were two monochrome adapters (Hercules and Tecmar) and \r
+the IBM Color Graphics Adapter (CGA). They have since quietly modified \r
+and extended their format on several occasions to support EGA, VGA and \r
+SuperVGA displays. Documentation is scarce, incomplete and sometimes \r
+contradictory. There's a small booklet available from ZSoft that \r
+describes the current version (with several omissions), a sample Pascal \r
+program from their CompuServe forum (GO WINAPB), a few magazine articles, \r
+and chapters in a few books (see the references at the end of this \r
+article). \r
+\r
+Personally, I think it's about time to remedy this situation. The \r
+following is a complete set of technical specifications for the current \r
+version of PCX. All of the information has been derived from printed \r
+information provided by ZSoft and conversations with their Technical \r
+Services department. This is it, folks! We now have formal (if not \r
+exactly official) specifications to work with when including the PCX \r
+graphics file format in our application programs. \r
+\r
+My original plan was to include sample C source code for reading and \r
+writing PCX image files. However, both this article and the source code \r
+grew to the extent that one had to go. If you don't want to develop your \r
+own PCX file handling routines from scratch, PCX_LIB is available through \r
+the CUG Library as CUG Volume #???. It includes fully commented C source \r
+code for reading and writing PCX image files, complete with software \r
+drivers for Hercules, CGA, EGA, and VGA display adapters.\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+ p. 1\r
+\f\r
+PCX Specifications \r
+\r
+The PCX graphics file format (Version 5) is designed to store monochrome \r
+and color bit-mapped images of any resolution with palettes of up to 256 \r
+simultaneous colors. It was originally designed for MS-DOS \r
+microcomputers, but is adaptable to other bit-mapped graphic \r
+environments. A simple but effective byte-oriented, run-length encoding \r
+scheme is used to compress the image data.\r
+\r
+There are two or three sections to a PCX graphics file - a 128-byte \r
+header, the encoded image data (which can be of any length) and an \r
+optional 256-color palette (see Figure 1). This palette is appended to \r
+the file only if the image contains more than 16 colors. \r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+ p. 2\r
+\f\r
+1. PCX File Header\r
+\r
+The file header describes the graphical environment in which the image is \r
+to be displayed. The information contained in the header is somewhat \r
+device-dependent in that the PCX file format implicitly assumes the \r
+presence of a standard IBM PC-compatible display adapter. Furthermore, \r
+the specific type and video mode of the adapter needed to display the \r
+image correctly cannot be uniquely determined from the file header \r
+information. It is in general the user's responsibility to ensure that \r
+the correct video mode has been selected before displaying a PCX image. \r
+\r
+The file header structure is shown in Figure 2. A complete description \r
+of each structure member is as follows: \r
+\r
+1.1 PCX Flag\r
+\r
+A constant value (0x0a) that signifies a PCX image file. \r
+\r
+1.2 Version\r
+\r
+Indicates the PCX file format version. It can be one of five values: \r
+\r
+ 0 - Version 2.5 of PC Paintbrush.\r
+ 2 - Version 2.8 (with palette information).\r
+ 3 - Version 2.8 (without palette information).\r
+ 4 - PC Paintbrush for Windows (not 3.0).\r
+ 5 - Version 3.0 and greater of PC Paintbrush and Paintbrush Plus, \r
+ including Publisher's Paintbrush. \r
+\r
+Most commercial programs supporting the PCX file format conform to \r
+Version 5. See Section 3, "Color Palettes", for further information. \r
+\r
+1.3 Encoding (1)\r
+\r
+A constant value (0x01) that indicates run-length encoding was used to \r
+encode and compress the image data. \r
+\r
+1.4 Bits per Pixel\r
+\r
+The number of bits per pixel per color plane (typically 1, 2, 4 or 8). \r
+\r
+1.5 Window\r
+\r
+A structure with the following members: \r
+\r
+ Name Bytes Description\r
+\r
+ xul 2 Upper left corner horizontal position\r
+ yul 2 Upper left corner vertical position\r
+ xlr 2 Lower right corner horizontal position\r
+ ylr 2 Lower right corner vertical position\r
+\r
+These members describe the position and size of the image within the \r
+display, and are measured in pixels (starting with zero). \r
+\r
+\r
+\r
+\r
+\r
+ p. 3\r
+\f\r
+1.6 HDPI (2)\r
+\r
+"Horizontal dots per inch". The value represents the horizontal \r
+resolution of the device used to create the image. \r
+\r
+1.7 VDPI (2)\r
+\r
+"Vertical dots per inch". The value represents the vertical resolution \r
+of the device used to create the image. \r
+\r
+1.8 Color Map\r
+\r
+The color palette to be used when displaying an image with 16 or fewer \r
+colors. See Section 3, "Color Palettes", for further information. \r
+\r
+1.9 Reserved\r
+\r
+This member was used to indicate the appropriate MS-DOS video mode in \r
+previous PCX file format versions. It is ignored in Version 5, but\r
+should be set to zero.\r
+\r
+1.10 NPlanes\r
+\r
+The number of color planes used to display the image (typically 1 or 4). \r
+See Section 3, "Color Palettes", for further information. \r
+\r
+1.11 Bytes per Line\r
+\r
+The number of bytes required for a buffer when decoding one color plane \r
+scan line. This value should be an even number (for compatibility with \r
+some existing commercial programs). See Section 2, "Image Encoding and \r
+Decoding", for further information. \r
+\r
+1.12 Palette Info (3)\r
+\r
+A bit-mapped variable indicating how to interpret the color palette. \r
+Only the lowest two bits are significant; the others are ignored. It \r
+can have one of two possible values: \r
+\r
+ 0x01 - color or black & white\r
+ 0x02 - grayscale\r
+\r
+If the variable is set to 0x02 (grayscale), the color palette must be set \r
+to shades of gray. \r
+\r
+1.13 HScreen Size (4)\r
+\r
+Horizontal screen size in pixels.\r
+\r
+1.14 VScreen Size (4)\r
+\r
+Vertical screen size in pixels.\r
+\r
+1.15 Filler\r
+\r
+Blank space to fill out 128-byte header. All bytes within this member \r
+should be set to zero. \r
+\r
+\r
+ p. 4\r
+\f\r
+Notes\r
+\r
+1. ZSoft has reserved the right to change the encoding scheme for better \r
+ image compression performance in future versions. \r
+\r
+2. Horizontal and vertical resolution for video display adapters is \r
+ defined as the total number of displayed pixels for the current video \r
+ mode. For scanners, it is defined in terms of dots per inch. (These \r
+ values are provided for information only. They are not required for \r
+ encoding or decoding PCX image files.) \r
+\r
+3. The "palette info" member of the file header was used in previous \r
+ versions of the PCX file format to indicate whether the palette \r
+ represented a color or grayscale palette. If it was set to 0x02 (as a \r
+ bitmap - the upper 6 bits could be set at random), the file decoding \r
+ functions could assume a default grayscale palette if necessary. \r
+ However, the palette already had a true (and possibly nonlinear) \r
+ grayscale, so the "palette info" member was never really used by \r
+ ZSoft. The current PC Paintbrush IV and IV Plus products simply \r
+ ignore it. \r
+\r
+4. The "HScreen Size" and "VScreen Size" members were added to Version 5 \r
+ of the PCX format to support PC Paintbrush IV Version 1.02 and IV Plus \r
+ Version 1.0. Since earlier Version 5 PCX files may contain \r
+ uninitialized data in place of these members, ZSoft specifically \r
+ recommends that they not be used to determine the appropriate video \r
+ mode for displaying the files.\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+ p. 5\r
+\f\r
+2. Image Encoding and Decoding \r
+\r
+The PCX graphics file format considers an image to be a contiguous \r
+sequence (block) of eight-bit bytes representing a bit-mapped raster \r
+display. A simple byte-oriented, run-length encoding (RLE) scheme is\r
+used to compress the display data. When the display is represented by\r
+more than one color plane (such as color images on EGA displays), each\r
+scan line is stored sequentially by color plane. \r
+\r
+The run-length encoding scheme uses a byte pair consisting of a "count" \r
+byte and a following "data" byte to represent sequences of display bytes \r
+with the same value. A count byte is uniquely identified by having its \r
+two most significant bits set; its six least significant bits are used to \r
+represent the count value (1 to 63). The following data byte is the \r
+value that is repeated in the display data the number of times indicated \r
+by the count value. \r
+\r
+Any display data byte which is not part of a sequence of bytes of the \r
+same value and which does not have its two most significant bits set is \r
+stored as itself in the encoded image data. Single display data bytes \r
+with a value of 0xc0 or greater are encoded with a count value of one. \r
+\r
+2.1. Decoding\r
+\r
+Decoding display data from encoded image data is done on a line-by-line \r
+basis. The pixel dimensions of the displayed image are calculated as: \r
+\r
+ horz_size = Window.xlr - Window.xul + 1\r
+\r
+and\r
+\r
+ vert_size = Window.ylr - Window.yul + 1\r
+\r
+The number of bytes required to buffer one complete scan line for all \r
+color planes in sequence is: \r
+\r
+ buffer_size = NPlanes * Bytes per Line\r
+\r
+Since there are always an integral number of bytes in the buffer, there \r
+may be unused data at the end of each color plane scan line if the number \r
+of bits per pixel is other than eight. This unused data should be masked \r
+off when transferring the line buffer contents to the video display \r
+adapter memory. \r
+\r
+In theory, each color plane scan line may contain an even or odd number \r
+of bytes. However, some application programs expect an even number of \r
+bytes. ZSoft ensures that their products create PCX files with an even \r
+number of bytes per color plane scan line, and recommends that other \r
+programs do the same for compatibility. Of course, decoding functions \r
+should be able to read files with either an even or odd number of bytes \r
+per color plane scan line. \r
+\r
+Decoding begins with the first scan line and proceeds by examining each \r
+byte of the encoded image data. If the two most significant bits of the \r
+byte are set, the lower six bits indicate how many times the next byte is \r
+\r
+\r
+\r
+\r
+ p. 6\r
+\f\r
+Decoding begins with the first scan line and proceeds by examining each \r
+byte of the encoded image data. If the two most significant bits of the \r
+byte are set, the lower six bits indicate how many times the next byte is \r
+to be duplicated in the line buffer. If these two bits are not set, the \r
+byte itself is copied (once) to the line buffer. A count is kept of the \r
+number of bytes in the line buffer. The current scan line is complete \r
+when its value equals "buffer_size". \r
+\r
+If the display contains more than one color plane, each plane is decoded \r
+in sequence. The order in which they are decoded is device-dependent. \r
+For instance, the Enhanced Graphics Adapter has four color planes ordered \r
+as blue, green, red and intensity. The beginning of each color plane \r
+scan line within the line buffer is given by: \r
+\r
+ offset = plane_number * Bytes per Line\r
+\r
+where "plane_number" is a number between 0 and NPlanes - 1. \r
+\r
+A decoding break occurs at the end of each scan line. That is, an \r
+encoding byte pair can only represent a contiguous sequence of bytes \r
+within the current scan line. However, this is not necessarily true for \r
+color planes. An encoding byte pair may represent a contiguous sequence \r
+of identical bytes that extends across two color planes for one display \r
+image scan line. \r
+\r
+Decoding continues until all scan lines (as indicated by "vert_size") \r
+have been decoded. Some older versions of PC Paintbrush padded the image \r
+with extra (uninitialized) scan lines so that all blocks of scan lines (8 \r
+or 16 lines) read from the file were the same size. The image data was \r
+read until end-of-file was returned. ZSoft no longer uses this \r
+technique, since it conflicts with the appended color palette (see \r
+Subsection 3.3, "VGA 256-Color Palettes"). The extra data read could \r
+also overrun the user's image buffer. \r
+\r
+A sample C function to decode a complete image scan line (all color planes)\r
+from a PCX file is shown in Figure 3. \r
+\r
+2.2. Encoding\r
+\r
+Encoding display image data is also done on a line-by-line basis, \r
+following the order of scan lines stored in the display adapter's memory \r
+buffer. The current scan line is encoded for each color plane on a per-\r
+byte basis. As noted above, ZSoft recommends that all color plane scan \r
+lines be padded if necessary to ensure they contain an even number of \r
+bytes. \r
+\r
+ZSoft also recommends that the data used to pad the last one or two bytes \r
+of a scan line represent white data. Apparently, some application \r
+programs display this data when printing or faxing the files.\r
+\r
+A sample C function to encode a single monochrome or color image scan \r
+line for a PCX file is shown in Figure 4.\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+ p. 7\r
+\f\r
+3. Color Palettes \r
+\r
+The PCX file format supports color palettes of up to 16 colors in the \r
+file header. Larger palettes (up to a maximum of 256 colors) are stored \r
+in an optional color palette that is appended to the encoded image data \r
+portion of the file. \r
+\r
+The file header color palette has two different formats, both designed \r
+for IBM PC-compatible machines. A device-specific palette is used for \r
+Color Graphics Adapters (CGA), and a standard R-G-B palette is used for \r
+Enhanced Graphics Adapters (EGA), Multicolor Graphics Adapters (MCGA), \r
+Video Graphics Adapters (VGA) and extended Video Graphics Adapters \r
+(SuperVGA). \r
+\r
+ZSoft's PC Paintbrush products no longer support the CGA color palette. \r
+The following information is provided only for compatibility with older \r
+PCX files. \r
+\r
+3.1. CGA Color Palettes\r
+\r
+The PCX format supports eight possible CGA color palettes for video modes \r
+4 (320x200 4-color graphics) and 5 (320x200 monochrome graphics, color \r
+burst off). Each palette consists of a background color and three \r
+foreground colors (or shades of grey). The background can be one of 16 \r
+colors, the value for which is stored in the first byte of the PCX file \r
+header Color Map member. Only the upper four bits are significant; the \r
+value must be right-shifted by four bits (or divided by 16) to determine \r
+the appropriate CGA hardware palette register value. \r
+\r
+The foreground color palette is specified by the fourth byte of the Color \r
+Map, which has the following structure: \r
+\r
+ Name Bit Description\r
+\r
+ Color Burst Enable 7 0 - color\r
+ 1 - monochrome\r
+ Palette 6 0 - yellow\r
+ 1 - white\r
+ Intensity 5 0 - dim\r
+ 1 - bright\r
+\r
+The lower five bits are ignored. \r
+\r
+Most published descriptions of the ROM BIOS call "Set CGA Palette" \r
+(Interrupt 16, Function 11) document only two palettes, obtainable by \r
+setting register BL to 0x00 or 0x01. This is equivalent to the "Palette" \r
+bit above. However, the palette intensity (equivalent to the "Intensity" \r
+bit above) can be selected using bit 4 of the BL register (0 = dim, 1 = \r
+bright). \r
+\r
+The original CGA display adapter was designed for use with NTSC composite \r
+video monitors and color televisions. The "color burst" is a periodic \r
+burst of a 3.58 MHz signal superimposed on the composite video signal to \r
+synchronize the phase of the monitor's internal 3.58 MHz oscillator. \r
+(Without synchronization, the picture has drifting color bars.) The \r
+presence or absence of the burst determines whether the image is \r
+displayed in color or monochrome. \r
+\r
+\r
+ p. 8\r
+\f\r
+The "Color Burst Enable" bit above actually indicates whether the MS-DOS \r
+video mode is to be 4 (color) or 5 (monochrome). However, the color \r
+burst signal has no meaning for RGB monitors. Video mode 5 will produce \r
+only two distinct color palettes on CGA displays adapters with RGB \r
+monitors, and three distinct palettes on EGA, VGA and SuperVGA display \r
+adapters emulating a CGA display. \r
+\r
+Under video mode 6 (640 x 200 2-color graphics), the first byte of the\r
+CGA color palette specifies the foreground color (i.e. - the color of\r
+the displayed pixels).\r
+\r
+3.2. EGA/VGA 16-Color Palettes\r
+\r
+The 16-color palette for EGA, MCGA, VGA and SuperVGA displays is an array \r
+of 16 elements, each a structure with the following members: \r
+\r
+ Name Bytes Description\r
+\r
+ Red 1 Red intensity\r
+ Green 1 Green intensity\r
+ Blue 1 Blue intensity\r
+\r
+All color map entries are stored as unsigned bytes with values ranging \r
+between 0 and 255. Where display adapters support fewer intensity \r
+levels, the value of each color map entry is interpreted by dividing its \r
+value by 256/n, where n is the number of allowable intensity levels \r
+(typically 2, 4 or 16). \r
+\r
+3.3. VGA 256-Color Palettes\r
+\r
+The 256-color palette for MCGA, VGA and SuperVGA displays is an array of \r
+256 elements, each a structure with the same members as the EGA/VGA 16-\r
+color palette, which is appended to the encoded image data portion of the \r
+file (see Figure 1). It is always preceded by a constant byte flag with\r
+the value 0x0c (12 decimal). \r
+\r
+Only Version 5 PCX-format files support 256-color palettes, and then only \r
+when the image has more than 16 colors. ZSoft recommends the following \r
+technique to determine if a 256-color palette is present: first verify \r
+that the file version number is 5, then count back 769 bytes from the end \r
+of the file. If the value of this byte is not 0x0c, the optional 256-\r
+color palette is not present and the EGA/VGA 16-color file header palette \r
+should be used. \r
+\r
+It is possible that a Version 5 PCX-format file with a valid file header \r
+palette can have the value 0x0c in the 769th byte from the end of the \r
+encoded image data. The above technique would then falsely indicate the\r
+presence of an appended 256-color palette. To avoid this problem, it is \r
+necessary to first decode the image and note the file position where the \r
+encoded image data section ends before counting back 769 bytes from the \r
+end of the file. If the supposed 256-color palette flag is located in \r
+the image data section, then the file header palette should be used \r
+instead.\r
+\r
+\r
+\r
+\r
+\r
+\r
+ p. 9\r
+\f\r
+3.4. 24-Bit Color \r
+\r
+Future versions of ZSoft's Publisher's Paintbrush will support up to 16.7 \r
+million simultaneous colors. The PCX file format will be based on three \r
+color planes (red, green and blue), with 8 bits per pixel per plane. \r
+There will be no color palette, since the color of each pixel will be \r
+fully specified by the encoded image data. \r
+\r
+3.5. Disabling the Palette \r
+\r
+It is occasionally necessary to disable the color palette of a PCX file \r
+in order to correctly display the image. In other words, the current \r
+(default) setting of the display adapter's palette registers are used. \r
+This can be done by changing the PCX file version number from '5' to '3' \r
+(i.e. - PC Paintbrush Version 2.8 without palette information). The file \r
+decoding functions must then check the file version number and ignore the \r
+color palette if it is set to '3'.\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+ p. 10\r
+\f\r
+4. Other Environments \r
+\r
+While the PCX file format was designed for MS-DOS machines, it is \r
+nevertheless possible to display PCX images on other machines. It will \r
+generally be necessary to map the image representation (i.e. - window \r
+dimensions, number of color planes, bits per pixel per plane, and the \r
+color palette) to the capabilities of the display hardware. \r
+\r
+It is also necessary to remember that all information in a PCX-format \r
+file is stored as either 8-bit bytes or 16-bit words. Words are stored \r
+in the big-endian format characteristic of 80x86-based machines. That \r
+is, the eight least significant bits (lower byte) are stored first, \r
+followed by the eight most significant bits (upper byte). If PCX-format \r
+files are transferred to little-endian machines (such as those based on \r
+680x0 and Z8000 processors), the order of bytes within each word will \r
+have to be reversed before they can be interpreted. (This applies to the \r
+file header only, since the encoded image data and optional 256-color \r
+palette are stored as bytes.)\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+ p. 11\r
+\f\r
+References \r
+\r
+Azer, S. [1988]. "Working With PCX Files", Microcornucopia, No. 42 \r
+(July-August), p. 42.\r
+\r
+Lindley, C.A. [1990]. Practical Image Processing in C, John Wiley & Sons \r
+Inc., New York, N.Y.\r
+\r
+Luze, M. [1991]. "Printing PCX Files", C Gazette, Vol. 5:2 (Winter 1990 -\r
+1991), pp. 11-22.\r
+\r
+Phoenix Technologies Ltd. [1989]. System BIOS for IBM PC/XT/AT Computers \r
+and Compatibles, Addison-Wesley, Reading, MA.\r
+\r
+Quirk, K. [1989]. "Translating PCX Files", Dr. Dobb's Journal, Vol. 14:8 \r
+(August), pp. 30-36, 105-108.\r
+\r
+Rimmer, S. [1990]. Bit-Mapped Graphics, Windcrest Books, Blue Ridge \r
+Summit, PA.\r
+\r
+ZSoft Corporation [1988]. PCX Technical Reference Manual Revision 4,\r
+ZSoft Corporation, Marietta, GA.\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+ p. 12\r
+\f\r
+Figures\r
+\r
++--------------------------------------------+\r
+| File Header (128 bytes) |\r
++--------------------------------------------+\r
+| Encoded Image Data (variable length) |\r
++--------------------------------------------+\r
+| Optional Color Palette (769 bytes) |\r
++--------------------------------------------+\r
+\r
+Figure 1 - Basic PCX File Format\r
+\r
+\r
+Name Bytes Description \r
+\r
+PCX Flag 1 Constant flag\r
+Version 1 PCX version number\r
+Encoding 1 Run-length encoding flag\r
+Bits per Pixel 1 Number of bits per pixel per plane\r
+Window 8 Window dimensions\r
+HDPI 2 Horizontal image resolution\r
+VDPI 2 Vertical image resolution\r
+Color Map 48 Hardware R-G-B color palette\r
+Reserved 1 (Used to contain video mode)\r
+NPlanes 1 Number of color planes\r
+Bytes per Line 2 Number of bytes per scan line\r
+Palette Info 2 Palette interpretation\r
+HScreen Size 2 Horizontal screen size\r
+VScreen Size 2 Vertical screen size\r
+Filler 54 Initialized filler bytes\r
+\r
+Figure 2 - PCX File Header Structure\r
+\r
+\r
+/* Read an encoded scan line (all color planes) from a */\r
+/* PCX-format image file and write the decoded data to a scan */\r
+/* line buffer */\r
+\r
+void pcx_read_line\r
+(\r
+ unsigned char *linep, /* PCX scan line buffer pointer */\r
+ FILE *fp, /* PCX image file pointer */\r
+ int bpline /* # bytes per line (all color planes) */\r
+)\r
+{\r
+ int data; /* Image data byte */\r
+ int count; /* Image data byte repeat count */\r
+ int offset = 0; /* Scan line buffer offset */\r
+\r
+ while (offset < bpline) /* Decode current scan line */\r
+ {\r
+ data = getc(fp); /* Get next byte */\r
+\r
+ /* If top two bits of byte are set, lower six bits show how */\r
+ /* many times to duplicate next byte */\r
+\r
+\r
+\r
+\r
+ p. 13\r
+\f\r
+ if ((data & 0xc0) == 0xc0)\r
+ {\r
+ count = data & 0x3f; /* Mask off repeat count */\r
+ data = getc(fp); /* Get next byte */\r
+ memset(linep, data, count); /* Duplicate byte */\r
+ linep += count;\r
+ offset += count;\r
+ }\r
+ else\r
+ {\r
+ *linep++ = (unsigned char) data; /* Copy byte */\r
+ offset++;\r
+ }\r
+ }\r
+}\r
+\r
+Figure 3 - Decode PCX Image File Scan Line Function\r
+\r
+\r
+/* Encode a scan line and write it to a PCX file (the line is */\r
+/* assumed to contain the color plane scan lines in sequence, */\r
+/* with padding for an even number of bytes and trailing white */\r
+/* data for each line as appropriate) */\r
+\r
+void pcx_write_line\r
+(\r
+ unsigned char *linep, /* Scan line buffer pointer */\r
+ int length, /* Scan line buffer length (in bytes) */\r
+ FILE *fp /* PCX file pointer */\r
+)\r
+{\r
+ int curr_data; /* Current data byte */\r
+ int prev_data; /* Previous data byte */\r
+ int data_count; /* Data repeat count */\r
+ int line_count; /* Scan line byte count */\r
+\r
+ prev_data = *linep++; /* Initialize the previous data byte */\r
+ data_count = 1;\r
+ line_count = 1;\r
+\r
+ while (line_count < length) /* Encode scan line */\r
+ {\r
+ curr_data = *linep++; /* Get the current data byte */\r
+ line_count++; /* Increment line byte count */\r
+\r
+ if (curr_data == prev_data) /* Repeating data bytes ? */\r
+ {\r
+ data_count++; /* Increment data repeat count */\r
+\r
+ if (data_count == 0x3f) /* Max allowable repeat count ? */\r
+ {\r
+ pcx_encode(prev_data, data_count, fp); /* Encode data */\r
+ data_count = 0;\r
+ }\r
+ }\r
+\r
+\r
+\r
+\r
+ p. 14\r
+\f\r
+ else /* End of repeating data bytes */\r
+ {\r
+ if (data_count > 0)\r
+ pcx_encode(prev_data, data_count, fp); /* Encode data */\r
+\r
+ prev_data = curr_data; /* Current data byte now prev */\r
+ data_count = 1;\r
+ }\r
+ }\r
+\r
+ if (data_count > 0) /* Any remaining data ? */\r
+ {\r
+ pcx_encode(prev_data, data_count, fp); /* Encode data */\r
+ }\r
+}\r
+\r
+\r
+/* Write an encoded byte pair (or single byte) to a file */\r
+\r
+void pcx_encode\r
+(\r
+ int data, /* Data byte */\r
+ int count, /* Data byte repeat count */\r
+ FILE *fp /* PCX file pointer */\r
+)\r
+{\r
+ if (((data & 0xc0) == 0xc0) || count > 1)\r
+ {\r
+ putc(0xc0 | count, fp); /* Write count byte */\r
+ }\r
+\r
+ putc(data, fp); /* Write data byte */\r
+}\r
+\r
+Figure 4 - Encode Image Scan Line Functions\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+ p. 15\r
+\r