Convert XPM Images to PPM with xpmtoppm

An XPM file is an X11 pixmap frozen in header-like text, and xpmtoppm is the tool that drags it into a usable PPM image. You will convert the file, confirm the result has the expected dimensions, and optionally save any transparency as a separate PBM mask. The examples use the installed Netpbm 11.5.2 command from package netpbm version 2:11.05.02-1.1build1.

Allow about ten minutes. You need a shell, a readable XPM file, and permission to write in the output directory. The conversion itself normally needs no elevated privileges. Do not use sudo unless the input or destination permissions genuinely require it.

Checkpoint: This guide creates new image files. It does not alter the XPM input, but shell redirection can truncate an existing destination before xpmtoppm starts.

1. Check the installed command

Confirm which executable will run and record the Netpbm version. These are ordinary read-only commands:

$ command -v xpmtoppm
/usr/bin/xpmtoppm
$ xpmtoppm --version 2>&1 | sed -n '1,2p'
xpmtoppm: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
xpmtoppm: Built from source dated 2024-03-31 09:09:47

The man page describes XPM version 1 and version 3 input. It also warns that the parser accepts only a limited set of XPM version 3 features, so a file can be valid XPM and still be rejected by this converter.

2. Convert one XPM file to PPM

xpmtoppm writes the image to standard output. Give it an input path and redirect that output to a new PPM file:

$ xpmtoppm /path/to/input.xpm > converted.ppm

Replace /path/to/input.xpm with the real file. The command produces no progress message in its normal mode. A zero exit status means the conversion completed; it does not by itself prove that the image is the one you expected.

Verify the file without opening binary pixel data in a text editor:

$ file converted.ppm
converted.ppm: Netpbm image data, size = 640 x 480, rawbits, pixmap
$ head -c 3 converted.ppm
P6

The dimensions depend on the XPM. The useful checks are a non-empty file, the expected width and height in the file output, and a PPM magic number such as P6. Some systems or later tools may describe the same file with slightly different wording.

3. Protect an existing output file

Warning: The > operator truncates its destination before the converter runs. If converted.ppm already contains a useful image, convert to a temporary name and replace it only after the new file passes your checks:

$ xpmtoppm /path/to/input.xpm > converted.ppm.new
$ file converted.ppm.new
converted.ppm.new: Netpbm image data, size = 640 x 480, rawbits, pixmap
$ mv converted.ppm.new converted.ppm

If conversion fails, leave the old file in place and remove the incomplete temporary output after inspecting the error:

$ rm converted.ppm.new

That rm is irreversible for the temporary file, so check the name before running it. There is no state to undo in the XPM input: xpmtoppm only reads it.

4. Keep transparency in a PBM mask

By default, transparency information is discarded. Use --alphaout= to write a PBM transparency mask alongside the PPM:

$ xpmtoppm --alphaout=converted-alpha.pbm \
    /path/to/input.xpm > converted.ppm
$ file converted-alpha.pbm
converted-alpha.pbm: Netpbm image data, size = 640 x 480, rawbits, bitmap

The mask is a PBM file, not another PPM image. If the XPM contains no transparency information, the manual says the mask contains all white, opaque values. The image and mask are both written only when the command can complete successfully.

Passing --alphaout=- sends the transparency output to standard output and discards the image output. That is a specialised pipeline choice, not the normal conversion command. Do not combine it with the previous redirection unless you have deliberately designed a consumer for the PBM stream.

5. Inspect parser diagnostics when needed

Add --verbose when you need basic information about what was read:

$ xpmtoppm --verbose /path/to/input.xpm > converted.ppm
xpmtoppm: Width x Height:  640 x 480
xpmtoppm: no. of colors:  16
xpmtoppm: chars per pixel: 1

These messages go to standard error, so they do not become part of the PPM redirected from standard output. The exact counts depend on the input.

For a failure, preserve the diagnostic and test the input path first:

$ test -r /path/to/input.xpm && echo readable
$ xpmtoppm /path/to/input.xpm > converted.ppm
$ printf 'exit status: %s\n' "$?"

A missing file or permission error is different from an XPM syntax or feature rejection. The installed parser cannot handle an input line longer than 8K characters. It also has documented limitations around version 3 comment placement, colour definitions and older zero-byte-per-pixel files. Keep the original file while investigating, and do not "repair" it with a blind search-and-replace.

6. Use the PPM in the next tool

PPM is an uncompressed interchange format. Once its header and dimensions are correct, pass it to another image tool already installed on the machine. For example, if pnmtopng is available:

$ pnmtopng converted.ppm > converted.png
$ file converted.png
converted.png: PNG image data, 640 x 480, 8-bit/color RGB, non-interlaced

This is a separate conversion. xpmtoppm does not create PNG output, and the alpha PBM remains separate unless a later tool combines it with the image. Test that later command independently before deleting either source file.

Done means