The basics
What is an XPM file?
XPM is a colour image format for the X Window System, the graphics system of Unix and Linux desktops. Like its predecessor XBM, it's written as C source code, so programs can compile their icons into the program itself. Unlike XBM, it has colours, a transparent colour and a layout you can read: each pixel is a character, so you can see the picture in a text editor.
Daniel Dardailler and Colas Nahaboo at the Bull research centre in Sophia Antipolis, France, released the first XPM library in February 1989. Arnaud Le Hors took it over, added symbolic colours and colours per kind of display in 1990, and settled on C syntax as XPM version 3, which added hotspots and transparency. The library, libXpm, is still part of X.Org.
Where you'll meet XPM files:
- Icons in older X11 programs and window managers, and in programs that embed their icons as C code.
- Debian's menu system, which asks for menu icons in XPM: Debian's package checker, Lintian, flags a menu icon in another format as an error, since window managers aren't required to read PNG.
- GTK applications, through gdk-pixbuf's XPM loader. Since gdk-pixbuf 2.42.11 (April 2024) that loader is no longer built by default, together with those for formats such as BMP, TGA and XBM, so some distributions no longer ship it.
Modern desktops use PNG and SVG icons instead. XPM is still a handy format when you want an icon inside a C or C++ source file.
Anatomy
What's inside an XPM file
An XPM file is a C array of strings: a line of numbers, a colour table, and then the pixels, one string per row, one character per pixel. Here is a complete XPM file we wrote for this page and checked in three decoders and a C compiler: a 6 × 5 icon, a blue rounded square with a white centre and transparent corners. You can see the picture in the text.
/* XPM */
static char *dot[] = {
/* 99helpers example: 6 x 5 pixels, 3 colours, 1 char per pixel */
"6 5 3 1",
" c None",
". c #1E66F5",
"o c #FFFFFF",
" .... ",
"..oo..",
"..oo..",
"......",
" .... "
};- 1
/* XPM */The marker
A C comment that identifies the file as XPM version 3. It must come first: programs and file-type databases look for exactly these 9 bytes at the start.
- 2
static char *dot[] = {The C array
An array of strings with any name. A C program can
#includethe file and passdotto libXpm. Newer writers, such as ImageMagick, writestatic const char *. - 3
/* 99helpers example: 6 x 5 pixels, 3 colours, 1 char per pixel */A comment
C comments can go between the strings. Readers skip them, though some simple ones, Pillow's among them, don't expect a comment inside the colour table.
- 4
"6 5 3 1"The values line
Width 6, height 5, 3 colours, 1 character per pixel. Two more numbers can follow, the x and y of a hotspot for cursors, and then
XPMEXTif the file has extensions. - 5
" c None"A transparent colour
The first character, a space, is the pixel code.
cis the key for colour displays, andNonemeans transparent. libXpm turns theNonepixels into a mask, so the icon can have any shape. - 6
". c #1E66F5"A colour in hex
The pixel code
.is blue, as#RRGGBB. Colours can also be X11 colour names such aswhiteorSteelBlue. - 7
"o c #FFFFFF"White
The pixel code
ois white. With 1 character per pixel there are fewer than a hundred usable characters, so images with more colours use 2 or more characters per pixel. - 8
" .... "The first row of pixels
Exactly width × characters-per-pixel characters: 6 here. Spaces at both ends are the transparent corners, then four blue pixels.
- 9
"..oo.."More rows
One string per row, top to bottom. The white
ooin the middle rows is the centre of the icon. - 10
};The end
The array closes. Optional extension strings, ending with
XPMENDEXT, would come before it.
Under the hood
How an XPM file works
Inside the C array, an XPM file has up to four sections, each a run of strings:
| Section | What it holds |
|---|---|
| Values | width height ncolors cpp, then optionally x_hotspot y_hotspot and XPMEXT |
| Colours | One string per colour: the pixel code (cpp characters), then one or more key and colour pairs |
| Pixels | One string per row, width × cpp characters |
| Extensions | Optional: XPMEXT name data lines, ending with XPMENDEXT |
Each colour line can give a different colour for each kind of display, so one icon works on a colour screen, a greyscale one and a black-and-white one. The keys are:
| Key | Used on |
|---|---|
c | Colour displays |
g | Greyscale displays with more than 4 levels |
g4 | 4-level greyscale displays |
m | Monochrome (black and white) displays |
s | A symbolic name, such as border, that a program can map to any colour when it loads the icon |
A line such as "x c #FF0000 m black" means red on a colour screen and black on a monochrome one. A colour can be #RRGGBB (or a shorter or longer hex form), an X11 colour name, or None for transparent. Nothing is compressed: a 48 × 48 icon with 1 character per pixel has 2,304 characters of pixels, plus quotes, commas and line breaks.
Versions
XPM versions
- XPM1 (1989): close to XBM, with
#definelines for the size and characters instead of bits for the pixels. - XPM2 (1990): dropped the C code. A file starts with
! XPM2, followed by the same sections as plain lines without quotes. - XPM3 (1991): brought the C wrapper back, starting with
/* XPM */, with the strings otherwise like XPM2. It's the format every current tool means by XPM.
The XPM manual's last version, 3.4i, is from 1996, and the format hasn't changed since. Current tools expect XPM3, so a file that starts with ! XPM2 may need converting first.
Comparison
XPM vs XBM, PNG and GIF
| XPM | XBM | PNG | GIF | |
|---|---|---|---|---|
| Stored as | C source text | C source text | Binary, compressed | Binary, compressed |
| Colours | Any number, from a table | 2 | Up to 16 bits per channel | Up to 256 per frame |
| Transparency | On or off per pixel (None) | No; the background often shows through | Full alpha | On or off per pixel |
| Hotspot | Optional | Optional | No | No |
| Opens in a browser | No | No | Yes | Yes |
Use XPM when the image must live inside C code or a program asks for it. For everything else, PNG is smaller, has real alpha and opens everywhere. GIF is the nearest web format to XPM's idea of a palette with one transparent colour.
How to
How to open, edit and convert an XPM file
- Open and edit: GIMP opens and exports XPM (its exporter has no options). IrfanView and XnView open it too, and any text editor shows the source.
- Convert with ImageMagick:
magick icon.xpm icon.png, ormagick icon.png icon.xpmthe other way (convertin ImageMagick 6). Transparent pixels becomeNone, and partly transparent ones are rounded to fully transparent or opaque. - Convert with Netpbm:
xpmtoppm --alphaout=mask.pgm icon.xpm > icon.ppmwrites the colours and the transparency mask as separate files;ppmtoxpmgoes the other way. - Use in C:
#include "icon.xpm"and pass the array toXpmCreatePixmapFromData, or to a toolkit that takes XPM data, such as GTK'sgdk_pixbuf_new_from_xpm_data.
Troubleshooting
Common XPM problems
- A GTK program shows no icon or can't open an XPM file. On distributions that build gdk-pixbuf 2.42.11 or later with its defaults, the XPM loader is missing. Install the package with the extra loaders if your distribution has one, or convert the icon to PNG.
- One program reads the file, another refuses it. Readers differ in how much of the format they handle. Pillow's reader, for example, accepts only hex colours and no comments inside the colour table, and in our test with Pillow 12.3 it couldn't decode an image that used
None. Re-save the file with GIMP or ImageMagick, or convert it to PNG. - Colours come out wrong. The file uses an X11 colour name that the reader doesn't know, or a 12-digit hex colour (
#RRRRGGGGBBBB). Replace them with#RRGGBBvalues. - A C++ compiler warns about string constants.
static char *with string literals isn't valid ISO C++ (g++ warns that it forbids the conversion). Change it tostatic const char *. - The image is shifted or garbled. A pixel row has the wrong number of characters, or a pixel code isn't in the colour table. Each row must be exactly width × characters-per-pixel long.
Security
Is an XPM file safe? The libXpm bugs
An XPM file is data, but it's parsed by C code that dates from the late 1980s, and crafted XPM files have repeatedly found bugs in it:
| When | What | Fixed in |
|---|---|---|
| 2005 | Several integer overflows in libXpm, reachable with a crafted image (US-CERT VU#537878) | Patched libXpm releases |
| January 2023 | CVE-2022-44617 and CVE-2022-46285: crafted XPM files make libXpm hang. CVE-2022-4883: libXpm called external helper programs unsafely, a privilege escalation risk in setuid programs | libXpm 3.5.15 |
| October 2023 | CVE-2023-43786 and CVE-2023-43787: an XPM file loaded with XpmReadFileToPixmap triggers endless recursion or a heap overflow in libX11. CVE-2023-43788 and CVE-2023-43789: out-of-bounds reads in libXpm's parser | libX11 1.8.7 and libXpm 3.5.17 |
Keep libX11 and libXpm updated, and don't feed untrusted XPM files to old programs. And because an XPM file is C code, only #include files you've read or generated: the compiler will compile anything in them.
Sample files
There are no sample XPM files on this page yet. The icon in the anatomy is a complete XPM file: copy it into a text editor and save it as dot.xpm, or make one from any image with ImageMagick (magick input.png output.xpm, or convert in ImageMagick 6).
Put it online
Have an XPM file? Give it a link.
Drop an XPM file on 99helpers and it gets its own web address. Browsers don't display XPM, so anyone who opens the link downloads the file, ready for an image editor, a code editor or a build.
Questions
XPM files, frequently asked
What is an XPM file?
A colour image for the X Window System, written as C source code: a colour table, then one string of characters per row of pixels. It's used for icons in X11 and Linux programs.
How do I open an XPM file?
Open it in GIMP, IrfanView or XnView, or convert it with ImageMagick (magick icon.xpm icon.png). Any text editor shows the source. Browsers don't display XPM.
Does XPM support transparency?
Yes, on or off per pixel: a colour defined as None is transparent. There's no partial transparency.
Can I edit an XPM file in a text editor?
Yes. Each pixel is a character, so you can change colours in the colour table or redraw pixels by typing. Keep every row exactly the same length.
What is the difference between XPM and XBM?
XBM stores 1 bit per pixel, black and white only, as hex bytes. XPM stores any number of colours as characters, with a colour table and a transparent colour.
Is XPM still used?
Less and less. Older X11 programs, window manager themes and Debian menu entries use it, and some programs embed icons as XPM in their source. New desktop icons are PNG or SVG.
Are XPM files dangerous?
They contain no scripts, but crafted files have exploited bugs in libXpm and libX11, most recently in 2023. Keep those libraries updated.
Related formats
Other file types explained
Keep going
Related
Sources
- XPM Manual, version 3.4i (Arnaud Le Hors, 1996)
- Wikipedia: X PixMap
- X.Org Security Advisory, 3 October 2023: libX11 and libXpm (oss-security)
- Ubuntu USN-5807-1: libXpm vulnerabilities (January 2023)
- GNOME Discourse: Change in the gdk-pixbuf loaders built by default in 2.42.11
- Lintian: menu-icon-not-in-xpm-format
Last reviewed 27 October 2026.