Using libjpeg in C++

Just for fun I thought it would be interesting to write a quick program to convert .jpg images to an ASCII representation. Here’s a sample output:

I was surprised that there are not more examples online showing how to use libjpeg, and even fewer wrapping it in a more cpp-friendly manner.

I decided to make the functionality re-usable, so if you have a need to read in a .jpg file, modify it, and save it, then this is going to be useful to you.

One point of interest, the shrink() member function – initially I wrote it very simply. I went through each (new) pixel in turn and calculated it as the average of a box of pixels in the original, larger, bitmap. This worked fine, but at the time I knew it was inefficient. Jumping around a surrounding box means cache misses galore. The best way to do this is one line at a time – this means we’re processing data already in processor cache lines, and is simpler for the CPU to do correct branch prediction. The version you see in the current source was my more considered version – it ended up three times faster than the initial version (and as it’s on github you can compare it to the old version in the history). I’ve left the getAverage() member function in, in case it is useful for anyone, but no longer use it in shrink().

If you’re on a linux distro you’ll undoubtedly have libjpeg (or one of its forks) installed. To use it and my source, you’ll need to install the header files for it, with:

sudo apt install libjpeg-dev

You can also install it on Windows, as a test I used Microsoft’s vcpkg to get the header files.

You can see the code at https://github.com/md81544/libjpeg_cpp -you’ll want a C++11-compatible compiler for it. I’ve tested the latest version with both g++ and clang++.