Convert PPM Images to PCX Safely with ppmtopcx
Need a PCX file for a program that still refuses anything newer? Convert a PPM with ppmtopcx, pick the output format yourself when the automatic choice is not suitable, and verify the result before it can clobber anything. The examples use Netpbm 11.5.2, installed here as Debian package netpbm version 2:11.05.02-1.1build1. Allow about ten minutes if the input image is ready.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a readable PPM file, a shell, and permission to create the destination file. The conversion itself normally needs no elevated privileges. This guide does not touch system configuration or install a PCX viewer.
1. Check the installed command
Confirm which executable your shell will run and record the version reported by the installed Netpbm build:
$ command -v ppmtopcx
/usr/bin/ppmtopcx
$ ppmtopcx --version
ppmtopcx: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
...
The version output carries build details after the library version, so exact lines can differ between distributions. What matters is that the command is present and reports the Netpbm version you expect. The local manual page is dated 26 September 2020; the installed executable reports 11.5.2.
2. Convert to the default PCX format
ppmtopcx reads the PPM named on the command line and writes the PCX image to standard output. Redirect that to a new filename:
$ ppmtopcx /path/to/input.ppm > output.pcx
Do not use sudo just because the source image came from another account. Use it only if your normal account genuinely cannot read the source or write the destination, and check the permissions first. Redirection is performed by the shell, so a command such as sudo ppmtopcx input.ppm > output.pcx still writes output.pcx as your own user.
- 16 colours or fewer: the program creates a palette PCX and picks the smallest useful number of planes.
- 17 to 256 colours: it creates an 8-bit, one-plane PCX.
- Above 256 colours: it creates a 24-bit true-colour PCX.
This is a format decision, not a resize or quality setting.
Checkpoint
Verify the destination is a PCX file and the command returned success:
$ printf '%s\n' "$?"
0
$ file output.pcx
output.pcx: PCX ver. 3.0 image data bounding box ..., RLE compressed
The bounding box and colour description depend on the image. If the conversion fails, stop before you use the output: a failed redirect can still leave a truncated destination behind.
3. Select an explicit colour format
Use -8bit when a reader expects a 256-colour PCX, even if the input uses 16 colours or fewer:
$ ppmtopcx -8bit /path/to/input.ppm > output-8bit.pcx
$ file output-8bit.pcx
output-8bit.pcx: PCX ver. 3.0 image data bounding box ..., 8-bit colour, RLE compressed
Use -24bit when the destination must be true colour, even for an image with 256 colours or fewer:
$ ppmtopcx -24bit /path/to/input.ppm > output-24bit.pcx
$ file output-24bit.pcx
output-24bit.pcx: PCX ver. 3.0 image data bounding box ..., 3 planes each of 8-bit colour, RLE compressed
These options change the PCX representation. They do not add back detail an input has already lost to a small palette, and the 24-bit result can end up larger.
4. Keep a legacy palette stable
Some older PCX readers ignore the palette stored in the file and assume a fixed 16-colour mapping. In that case, use the built-in mapping with -stdpalette:
$ ppmtopcx -stdpalette /path/to/input.ppm > output-standard.pcx
The input must contain only colours from that standard palette, or the command fails. Netpbm provides pcxstd.ppm as the palette image; use pnmremap with a suitable palette image first when the source needs adapting. Do not combine -stdpalette with -palette=.
For a reader that needs a specific custom ordering, make a PPM palette file with one pixel per palette colour, then pass it with -palette=:
$ ppmtopcx -palette=/path/to/palette.ppm /path/to/input.ppm > output-custom-palette.pcx
Pixels are read left to right, then top to bottom, and become the PCX palette in that order. The aspect ratio of the palette image does not matter. Every input colour must occur in the palette or the conversion fails; use pnmremap before ppmtopcx if the source has colours outside the chosen palette.
5. Handle plane and position compatibility
Some old readers accept only particular numbers of planes. For the ordinary 16-colour palette form, -planes=1, -planes=2, -planes=3 or -planes=4 requests a specific value:
$ ppmtopcx -planes=4 /path/to/input.ppm > output-four-planes.pcx
This option only means anything for the non-packed 16-colour format: do not combine it with -24bit, -8bit or -packed. By default the program chooses the smallest number of planes that can represent the input colours.
The PCX header also stores an image position. Set it with -xpos= and -ypos=, both defaulting to zero:
$ ppmtopcx -xpos=10 -ypos=20 /path/to/input.ppm > output-positioned.pcx
Position is not padding: it changes the coordinates recorded in the PCX header, whereas pnmpad changes the pixels and dimensions of the image itself. The accepted range for each position is -32767 to 32768.
6. Avoid accidental replacement and recover from a bad output
Shell redirection truncates an existing destination before ppmtopcx starts. Choose a new name while testing, as with output-8bit.pcx above. If you must replace a known file, back it up first:
$ cp --preserve=all output.pcx output.pcx.bak
$ ppmtopcx -24bit /path/to/input.ppm > output.pcx.new
$ file output.pcx.new
$ mv -- output.pcx.new output.pcx
Warning
The mv is the state-changing step. If conversion or verification fails, leave the original alone and inspect or remove output.pcx.new deliberately. To undo a completed replacement, restore the backup with mv -- output.pcx.bak output.pcx once you have confirmed the backup is actually the file you want.
Done means
command -v ppmtopcxfound the intended Netpbm executable.- The conversion returned status 0 and wrote a new destination.
fileidentifies the destination as PCX with the expected colour form.- Chose a palette, plane count or image position only when the receiving reader actually requires it.
- No useful source or destination file was overwritten without a deliberate backup and check.