On stb

9 March 2026

stb is a family of very neat C headers that provide various cool things, including image encoding/decoding, font rasterization and voxel simulation, among others. in the last month, i have been experimenting with these headers, and the stb_image ones specifically, and i wanted to make a little write-up about how my experience went.

the first thing i did with the stb_image header is just reproducing the example usage, i.e loading the image and reading its metadata. i was quite unpleasantly shocked by how much time it took for it to compile (though i quickly realised this was the compiler's fault). after seeing my shitty code compile and, oh! actually do something, i was quickly taken over by a wave of enthusiasm and began messing around with what i had on hand.

conveniently enough, this is when i got a challenge to write a wallpaper setter for Xorg using exclusively stb_image, due to the fact that it can be easily statically linked. i took up the opportunity to start messing around, and after a few hours i had the result i was hoping for. obviously none was as easy as it sounds, and a lot of hurdles were actually met and promptly jumped over in the process. here is the general program flow:

as you can tell, the road was quite bumpy, but in the end i had a working result, a program that drew an image onto the root window, with only one (1!) library dependency (and also Xlib). it was really cool seeing the program compile, and actually do everything i needed it to do.. i think it's a very familiar feeling to most people. i ended up showing the program around to a few people, and was told it's 'really cool'. that must account for something!

after this, i spent a lot of time doing.. nothing, i was sort of burnt out and just messing around with other things. i then decided to reinstall my system and see how tidy and controlled i can keep it (maybe a bit on that later). in the process of said experimentation, i found my package count to be "worryingly" high (~480), ended up looking at my installed package list and found out there was a rogue imlib2 installed.. absolutely terrifying, right?

investigating the package's reverse dependencies, i found out that the reason it was installed was because of 2 packages: maim and nsxiv. if you aren't familiar with either of those terms, one is a screenshot tool, and the other is an image viewer. both of them happen to use imlib2, and this discovery led me to begin messing asround with stb_image for the 2nd time. this time round, i wanted to try writing a screenshot utility that would do everything i wanted from maim.

the program flow goes something like this (did you notice that i like lists?):

this time the aforementioned road was way, way less bumpy, partially due to the fact that it was no longer my 1st time writing something with stb_image, and partially because i didn't need to do any of the weird stuff i had to do with the wallpaper setter. to my surprise it ended up working on the first try! i tested it out on a few things, and found out it also somehow natively works with multiple monitors, to some extent. neat, i said, pushed it and forgot about it for the next week.

somewhere in that time i got the motivation to completely get rid of imlib2 on my system, and make an image viewer using stb_image. knowing that it would probably absolutely suck to do, i still went ahead and started messing around. this time the program flow was a bit more complex:

despite sounding relatively simple, this was by far the most annoying thing to get done. i was constantly messing up where i was and was not doing stuff, bilinear scaling made me physically sick, and i never had to do this much troubleshooting in my entire life. at the end of it, though, it was very much worth it to see it working and displaying my wallpaper gallery! a few issues i noted were the scaling was really slow with even relatively small images (1920x1080) and there was a big bottleneck with the whole drawing loop. though this is most definitely stb_image's problem, compared to the bazillion optimization imlib2 was doing, my program was still relatively quick!

for now, the image viewer is not close to being at full image parity with nsxiv, for example, it doesn't inherit the colors from xresources, it doesn't have thumbnails, slideshows, panning, mouse support... the list goes on! but at the very least i can now enjoy my package list, free of imlib2 ;)

in conclusion: while this was indeed a very grueling, annoying and simply boring experience, doing this made me learn a lot of things about the X server, C in general and the price of ibuprofen at the nearest pharmacy. have fun!

post scriptum, obviously i could not leave the article without the actual links to what i wrote, so here's the obligational self-plug to aw, so and vu.