Convert PBM Images to XBM with pbmtoxbm
An old X11 program wants its icon as C source rather than a picture file, and pbmtoxbm is the tool that turns a PBM bitmap into exactly that. You end up with an XBM file, its dimensions checked, and X11 or X10 format chosen on purpose rather than by accident. The examples use Netpbm 11.5.2, package version 2:11.05.02-1.1build1.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need a shell, the netpbm package, and a readable PBM file. Converting a bitmap does not need elevated privileges: skip sudo unless the input or destination directory is genuinely locked away from your account.
1. Check the installed command
Confirm which executable will run and note the Netpbm version before you trust anything below. Both checks are read-only:
$ command -v pbmtoxbm
/usr/bin/pbmtoxbm
$ pbmtoxbm --version
pbmtoxbm: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
pbmtoxbm: Built from source dated 2024-03-31 09:09:47
Everything after the first line of --version is build information, and it varies between machines. If command -v comes back empty, install Netpbm the normal way for your system, then run the check again. That is an administrative step, not part of the conversion itself.
Checkpoint
A path to pbmtoxbm and a readable PBM file, before you create any output.
2. Convert a PBM file to the default X11 format
The basic form is pbmtoxbm [options] [pbmfile]. Give the output a new filename so a failed run cannot wipe out an existing XBM:
$ pbmtoxbm input.pbm > output.xbm
$ file output.xbm
output.xbm: xbm image (8x4), ASCII text
Swap in your own file for input.pbm. The command writes XBM text to standard output, and the shell redirection is what actually creates output.xbm. X11 is already the default, so the explicit -x11 flag below changes nothing about the result, it just says so out loud:
$ pbmtoxbm -x11 input.pbm > output-x11.xbm
$ file output-x11.xbm
output-x11.xbm: xbm image (8x4), ASCII text
The dimensions in the file output come straight from your input, so yours will differ from the example. A non-zero exit status means the conversion failed: treat a half-written destination as junk, not as a usable image.
3. Inspect the generated XBM source
XBM is not a binary image container, it is C-like source you can read in a pager. Peek at the first few lines with sed:
$ sed -n '1,12p' output.xbm
#define input_width 8
#define input_height 4
static char input_bits[] = {
0xa5,0x5a,0xff,0x00};
The identifier is normally built from the input filename, followed by width and height defines and then the bitmap bytes themselves. Do not hand-edit the generated data to make it look like a normal image file: anything that consumes XBM expects this exact source shape.
Piping PBM data in on standard input works just as well:
$ pbmtoxbm < input.pbm > from-stdin.xbm
$ file from-stdin.xbm
from-stdin.xbm: xbm image (8x4), ASCII text
With no named file, the command falls back to a generic identifier such as noname. If the C identifier in the generated source actually matters to code that includes it, feed the command a named file instead.
4. Choose X10 only for a compatible consumer
Reach for -x10 only when the program on the receiving end specifically wants the older X10 XBM layout:
$ pbmtoxbm -x10 input.pbm > output-x10.xbm
$ file output-x10.xbm
output-x10.xbm: xbm image (8x4), ASCII text
$ sed -n '1,5p' output-x10.xbm
#define input_width 8
#define input_height 4
static short input_bits[] = {
On this Netpbm build, X10 output uses a static short data array where the default X11 output uses static char. The exact bytes depend on your PBM pixels either way. Do not pick X10 because it sounds more compatible: X11 is the default for a reason, and it is what current XBM consumers expect.
-x10 and -x11 are mutually exclusive. Ask for both and the command refuses:
$ pbmtoxbm -x10 -x11 input.pbm > rejected.xbm
$ printf 'exit status: %s\n' "$?"
exit status: 1
Clean up the rejected file before reusing its name. Safer still, write to a temporary name and only rename it into place after you have checked the result:
$ pbmtoxbm input.pbm > output.xbm.new
$ file output.xbm.new
output.xbm.new: xbm image (8x4), ASCII text
$ mv output.xbm.new output.xbm
That final mv replaces whatever output.xbm already existed. Only run it once you have inspected the new file and actually mean to replace the old one. If conversion fails, leave the old output alone and remove the incomplete .new file by hand once you have confirmed what it is.
5. Diagnose input and output mistakes
For an input problem, check the path and read permission without touching anything:
$ ls -l input.pbm
$ test -r input.pbm && echo readable
readable
A missing or unreadable file gives a non-zero exit status: check the spelling and the directory before anything else. Running the converter as root will not fix a wrong path, and it can leave root-owned files behind for you to clean up later.
Before a batch conversion, check the destination is writable:
$ test -w . && echo destination-directory-is-writable
destination-directory-is-writable
Shell redirection happens before pbmtoxbm even starts, so pbmtoxbm input.pbm > output.xbm truncates an existing output.xbm even if the input turns out to be invalid. Use a fresh destination, or the .new and mv pattern above, whenever the old file is worth keeping.
If file does not call the result XBM, check the exit status and read the first few lines yourself. An empty file, a stray error message caught by odd redirection, or a non-PBM input all need fixing before you hand the XBM to another program. Keep the original PBM around until the consumer has accepted the conversion.
Done means
- Command confirmed.
pbmtoxbmresolves to the Netpbm installation you intended, and you know its version. - Input checked. The PBM is readable and the XBM output is non-empty.
- Format verified.
filereports the expected dimensions and XBM format. - Format chosen deliberately. X11 stayed the default unless a compatible consumer needed
-x10. - Old files protected. Nothing was overwritten blindly, and the original PBM is still there if you need it.