File types · Explainer

The XBM file (.xbm)

An XBM file is an X BitMap: a black-and-white image written as a few lines of C source code, made so that X Window System programs could compile icons and cursors straight into their code. This guide explains how the bits are laid out, what the hotspot is for, why browsers stopped showing XBM, and how to open and convert one.

At a glance

Full name
X BitMap
Extensions
.xbm; also seen as .bitmap, .icon, or a C header .h
MIME type
None registered with IANA. image/x-xbitmap by convention, sometimes image/x-xbm
Kind
Plain text (C source code); 1 bit per pixel, uncompressed
Standard or owner
The X Window System; read and written by Xlib's XReadBitmapFile and XWriteBitmapFile
First released
With the X Window System in the mid-1980s; today's form is the X version 11 format (X11, 1987)
Colours
Two: each pixel is 1 (foreground, usually black) or 0 (background)
Magic number
None. The file starts with #define and the image's name
Opens with
GIMP, ImageMagick, XnView, IrfanView, FFmpeg, Pillow and any C compiler; current web browsers don't display it

The basics

What is an XBM file?

XBM is the bitmap format of the X Window System, the graphics system of most Unix and Linux desktops since the 1980s. It stores a black-and-white image as C source code, so a programmer can #include an icon or a cursor and have it compiled into the program, with no image library and no file to load at run time.

Xlib, the C library for writing X programs, has had functions to read and write the format from the start: XReadBitmapFile, XWriteBitmapFile and XCreateBitmapFromData. X also came with a bitmap editor that saves XBM files. For pictures with colour, X programs moved to XPM, which first appeared in 1989 and keeps the same idea of an image written as C code.

Today you'll meet XBM files:

  • In X11 programs and window managers, for cursors, small icons and button images. The Openbox window manager, for example, draws its title-bar buttons from XBM files in its themes.
  • In microcontroller projects, where a display library takes a 1-bit image as a C array; XBM is ready to paste in.
  • In old websites, from the early web, when browsers displayed XBM and simple hit counters were served as XBM images.

For anything else, use PNG: it can also store 1-bit images, compresses them, and opens everywhere.

Anatomy

What's inside an XBM file

An XBM file is C code: two #define lines with the width and height, two optional lines with a hotspot, and an array of bytes holding the pixels, 1 bit each. Here is a complete XBM file we wrote for this page and checked in five decoders and a C compiler: a 10 × 7 arrow cursor pointing left, with its hotspot at the tip. Below it, the same bytes drawn out as pixels.

arrow.xbm (complete file, 220 bytes)
#define arrow_width 10
#define arrow_height 7
#define arrow_x_hot 0
#define arrow_y_hot 3
static unsigned char arrow_bits[] = {
   0x08, 0x00, 0x0c, 0x00, 0xfe, 0x03, 0xff, 0x03, 0xfe, 0x03, 0x0c, 0x00,
   0x08, 0x00 };

The same bits drawn out (# is 1, . is 0):
row 0   0x08 0x00   ...#......
row 1   0x0c 0x00   ..##......
row 2   0xfe 0x03   .#########
row 3   0xff 0x03   ##########   ← hotspot at x 0, y 3
row 4   0xfe 0x03   .#########
row 5   0x0c 0x00   ..##......
row 6   0x08 0x00   ...#......
  1. 1#define arrow_width 10

    Width

    The width in pixels, as a C preprocessor constant. Every name in the file starts with the image's name, here arrow, taken from the file name when it was written. A program can #include two XBM files without the names clashing.

  2. 2#define arrow_height 7

    Height

    The height in pixels: 7 rows.

  3. 3#define arrow_x_hot 0

    Hotspot

    Optional. The _x_hot and _y_hot lines are only there if the bitmap has a hotspot: for a cursor, the pixel that marks where you're pointing. Here it's the tip of the arrow, x 0, y 3. Plain icons leave these lines out.

  4. 4static unsigned char arrow_bits[] = {

    The pixel array

    A C array of bytes in hexadecimal. The X11 specification says static unsigned char; ImageMagick and Netpbm write static char, and readers accept both.

  5. 50x08, 0x00,

    The first row

    Each row takes whole bytes: a 10-pixel row needs 2. The least significant bit of the first byte is the leftmost pixel. 0x08 is binary 00001000, so bit 3 is set: pixel 3 is black, the tip of the arrowhead's top edge.

  6. 60xfe, 0x03,

    Padding bits

    Row 2: 0xfe sets pixels 1 to 7, 0x03 sets pixels 8 and 9. The other 6 bits of 0x03 would be pixels 10 to 15, which don't exist. They're padding, and readers ignore them.

  7. 70x08, 0x00 };

    The end

    14 bytes: 7 rows of 2. Nothing marks where a row ends; a reader works it out from the width. There's no checksum, colour or metadata.

  8. 8row 3 0xff 0x03 ##########

    The bits drawn out

    Read each byte from its lowest bit to its highest, then the next byte, and you get the picture: an arrow pointing left. The hotspot sits on this row, at its left end.

Under the hood

How XBM stores pixels

The format is defined by what Xlib writes. In the X11 documentation it's five lines, with the hotspot lines optional:

The X version 11 bitmap file format (Xlib manual)
#define name_width width
#define name_height height
#define name_x_hot x
#define name_y_hot y
static unsigned char name_bits[] = { 0xNN,... }
  • 1 bit per pixel. 1 is the foreground, normally drawn black; 0 is the background. Many programs show 0 as transparent, so an XBM icon takes on the colour behind it.
  • Rows top to bottom, pixels left to right, unlike BMP, which stores rows bottom-up.
  • Least significant bit first. The leftmost pixel of a byte is its lowest bit. That's the opposite of PBM, where the leftmost pixel is the highest bit, and a common mistake in hand-written XBM code.
  • Each row is padded to whole bytes. A row of 10 pixels takes 2 bytes; the unused bits are ignored.
  • No compression and no colour. A 64 × 64 icon is 512 bytes of pixels, written out as about 3 KB of text.

X10 bitmaps

Before X11, the X version 10 format stored the pixels as 16-bit short values instead of bytes. GIMP can still export it (the "X10 format bitmap" option), but Xlib's documentation leaves reading anything other than the standard format up to the implementation, so prefer the X11 form.

History

Why browsers stopped showing XBM

In the early web, XBM was the simplest image format that wasn't owned by anyone, and graphical browsers, especially those on X, displayed it inline. It was used for small symbols and for hit counters, which a server script could write as text without an image library.

Support went away as the web settled on GIF, JPEG and PNG:

  • Internet Explorer dropped XBM in version 6.
  • Firefox removed its XBM decoder around Firefox 3.6. A side effect of the old decoder: a local text file starting with #define, such as C source code, could be mistaken for an XBM image.
  • WebKit removed its open-source XBM decoder in January 2010, noting that Mozilla and Internet Explorer had already done so. Chrome, then built on WebKit, lost XBM with it.

Treat XBM as unsupported on the web. To show a 1-bit image on a page, convert it to PNG or SVG.

Comparison

XBM vs XPM, PBM and PNG

XBMXPMPBMPNG
Colours2Any, via a colour table2Up to 16 bits per channel
Stored asC source, hex bytesC source, one or more characters per pixelText or binary, with a short headerBinary chunks, compressed
TransparencyBackground bits are often shown as transparentYes, colour NoneNoFull alpha
Hotspot for cursorsYesYesNoNo
Compiles into a C programYesYesNoNo
Opens in a browserNoNoNoYes

XPM is XBM's colour successor. PBM, from the Netpbm family, stores the same 1-bit pixels with the opposite bit order and is the usual go-between when converting. PNG is what to keep or share.

How to

How to open, create and convert an XBM file

  • Look at it: it's text, so any text editor shows the code. To see the picture, open it in GIMP, XnView or IrfanView (Windows).
  • Draw one: GIMP opens and exports XBM. Its export dialog can write hotspot values, a comment, a different name prefix and, since XBM has no transparency, a separate mask file made from the alpha channel. On X11 systems, the classic bitmap editor edits XBM files pixel by pixel.
  • Convert with ImageMagick: magick arrow.xbm arrow.png, or magick logo.png -resize 32x32 logo.xbm the other way (convert in ImageMagick 6). A colour image is reduced to black and white; add -threshold 50% and adjust the percentage to choose where the cut falls.
  • Convert with Netpbm: xbmtopbm arrow.xbm > arrow.pbm and pbmtoxbm arrow.pbm > arrow.xbm.
  • In Python: Pillow reads and writes XBM, including the hotspot: Image.open("arrow.xbm").info["hotspot"] gives (0, 3) for the example above.
  • Use it in C: #include "arrow.xbm" and pass arrow_bits, arrow_width and arrow_height to XCreateBitmapFromData, or to a display library on a microcontroller. Check the library's bit order first: some expect the most significant bit first.

Troubleshooting

Common XBM problems

  • The picture looks scrambled in groups of 8 pixels. The bit order is reversed: the reader or the display library expects the most significant bit first. Reverse the bits in each byte, or convert with a tool rather than by hand.
  • The image comes out inverted. Some programs draw 1 as white. Invert it (magick in.xbm -negate out.xbm) or swap the colours where it's drawn.
  • A C++ compiler rejects the file. ImageMagick and Netpbm write static char, and in C++ a value such as 0xFF doesn't fit a char that is signed, which g++ reports as a narrowing error. Change the type to unsigned char.
  • Two XBM files clash when included together. They share a name prefix, often because both were saved under the same file name. Rename the #define constants and the array.
  • It doesn't show in a browser. No current major browser decodes XBM. Convert it to PNG.

Security

Is an XBM file safe?

An image viewer reads an XBM file as text and never runs it, so opening one is as safe as the viewer's parser. Bugs have happened: in 2008 Mozilla fixed a low-severity flaw in Firefox 2's XBM decoder that could reveal small pieces of uninitialised memory.

The real care point is the C compiler. When you #include an XBM file, the compiler doesn't know it's meant to be an image: any C code in it is compiled into your program. Only include XBM files you've read or generated yourself.

Sample files

There are no sample XBM files on this page yet. The arrow in the anatomy is a complete XBM file: copy it into a text editor and save it as arrow.xbm, or make one from any image with ImageMagick (magick input.png output.xbm, or convert in ImageMagick 6).

Put it online

Have an XBM file? Give it a link.

Drop an XBM file on 99helpers and it gets its own web address. Browsers no longer display XBM, so anyone who opens the link downloads the file, ready for an image editor or a code editor.

Questions

XBM files, frequently asked

What is an XBM file?

A black-and-white image from the X Window System, written as C source code: the width and height as #define lines and the pixels as an array of bytes, one bit per pixel. It's used for icons and cursors.

How do I open an XBM file?

Open it in GIMP, XnView or IrfanView to see the picture, or in a text editor to see the code. Browsers don't display it.

How do I convert XBM to PNG?

Run magick input.xbm output.png with ImageMagick, or open it in GIMP and export as PNG. The result is a 1-bit image; nothing is lost.

Can XBM have colour?

No. Each pixel is one bit: foreground or background. For colour, use XPM or PNG.

What is the hotspot in an XBM file?

An optional point, given by _x_hot and _y_hot lines, that marks where a cursor points. For an arrow cursor it's the tip of the arrow.

Why don't browsers show XBM images any more?

Internet Explorer 6, Firefox (around version 3.6) and WebKit (in 2010) removed their XBM decoders, as the format had little use on the web. Convert XBM images to PNG to put them on a page.

Is an XBM file a C file?

Yes: it's valid C that a compiler accepts with #include. Image programs read the same text without compiling it.

Related formats

Other file types explained

Keep going

Related

Sources

Last reviewed 27 October 2026.