NERDBUDE

[ code. keyboards. terminals. cyber. ]

[HOWTO] [WHOAMI] [PODCAST] [GERMAN]

xpm



In my latest variant of XMobar sits a small green Space Invader in the upper left corner. This can be realized with XMobar by *.xpm file.
That's why today we have "fun with unusual file formats". XPM stands for "X PixMap" and is an ASCII text format. It is used to represent raster graphics. Mostly it is used for icons. XPM was developed in 1989 by Daniel Dardailler and Colas Nahaboo. The latter perhaps known by the GWM Windowmanager for X-Window systems.

The *.xpm format was defined so that an .xpm file is always valid C source code. This allows *.xpm files to be directly included in C code via #include.


The syntax of an .xpm file is straightforward and easy to understand.

Here is my SpaceInvader:

space_invader.xpm
/* XPM */
static char * spaceinvader_xpm[] = {
"20 20 2 1 XPMEXT",
"       c None",
".      c #afd75f",
"                    ",
"    ..        ..    ",
"    ..        ..    ",
"      ..    ..      ",
"      ..    ..      ",
"    ............    ",
"    ............    ",
"  ....  ....  ....  ",
"  ....  ....  ....  ",
"....................",
"....................",
".. .............. ..",
".. .............. ..",
".. ..          .. ..",
".. ..          .. ..",
"     ....  ....     ",
"     ....  ....     ",
"                    ",
"                    ",
"                    ",
"XPMEXT author PHØ   ",
"mailto:post@nerdbude.com",
"XPMENDEXT           "};


The *.xpm file consists of seven parts:

- header line
- declaration and beginning of assignment line
- values
- cColors
- pixels
- extensions
- end of assignment


header line

The header line consists of a C comment.

/* XPM */
This comment here is considered a "magic number" and defines that this is an .xpm file.

declaration and beginning of assignment line

In the declaration line a C variable is declared. The name of the variable is arbitrary, but must be a valid C identifier. Most often, simply the image name is used here.

static char * spaceinvader_xpm[] = {

values

The values contain 4 or 6 decimal numbers (only 4 in the example)

20 20 2 1

20 - width of the image in px
20 - Height of the image in px
2 - number of colors in the image
1 - Number of characters per pixel value


The last two characters (5 + 6) are values that indicate so-called hotspots, such as in a cursor the place to which the cursor points.
For normal images, however, you can safely ignore these and do not need them.
If extensions are used in the file, the 4/6 numbers are followed by XPMEXT (xpm extension).


cColors

The number of colors has already been determined in the Values (2).
Now it goes to the definition of the colors.

" c None", ". c #afd75f",

Each color definition consists of a character code. Different color definitions can also be specified here for different display types. Thus the *.xpm can be optimized for different color depths and need not be down-calculated to b/w each time. The following options are available:

c - colored
g - more than four shades of gray
g4 - four shades of gray
m - Monochrome
s - symbolic value (like Foreground or Background)

These options are followed by the actual color definition.
Either in HEX (#afd75f) or HSV (%80, 55.8, 84.3). Transparency is simply specified as "None".


pixels

Now comes the actual image or the information which pixel gets color and which remains transparent.
One pixel line in the image also corresponds to one line in the *.xpm file. Wonderful for ASCII Art and there are no limits to the imagination.

If you use *.xpm files in C code the image can also be guessed already in the source code.

extensions

Last but not least, our *.xpm file has the extensions. The extensions should be used in the following format:

"XPMEXT extension_name extension_value"

So in the case of the Space Invader like this:

"XPMEXT author PHØ" "mailto:post@nerdbude.com", "XPMENDEXT"};

The XPMENDEXT at the end closes the extensions. And "};" closes the C declaration.

So what's the point of *.jpg and *.gif when you can have *.xpm.
By the way, this is what the little guy looks like:


and you can find it on Github:

Link (Github)



//EOF