Imgtiger

24 November 2019 2 min read Category: programming Tags: rust macos

Imgtiger is an image viewer for the iTerm2 terminal emulator on OSX. I created imgtiger because the refrence-implementation image viewer, imgcat, was quite slow. I looked into it and found it was a shell script. Shell scripts are notoriously slow, so I thought it would be quite easy to create a faster version, and it was.

I started by reading the source code for imgcat to figure out how it worked. It's quite simple, iTerm2 has a custom escape code that can be used to display an image. The documentation for this escape code can be found here.

In short, the escape code follows this format:

\033]1337;File=[extra options]:<base64 encoded file contents>

Those extra options can be things like filename, size, width, height, and how to display the image.

In my upgraded version of imgcat I had two goals. One was to make imgcat but faster, and the second one was to make all the options from the escape code available. I added command flags that corrospond to each option in the escape code, and added much better help screen to explain the options.

As I was making imgtiger I found that the escape code was quite complex, so I split imgtiger into two parts, an API for the escape code and a CLI interface to the API. The imgtiger binary is just a CLI interface for the imgtiger API. Both are publicly available on crates.io.

During development I wanted to see how much I had improved upon imgcat, so I got an image of a tiger from flickr to use as a test. I also pulled a 4K render of an old blender project to serve as a large image transfer test.

Using hyperfine, an excelent CLI benchmarking tool, I measured the performance of both imgcat and imgtiger. Using the following command I tested both implementations.

hyperfine -w5 "<image_viewer> <test_image>"

With a 3000x2000 jpeg image, imgcat ran in 1.301s ± 0.007s. Imgtiger ran in 15.9ms ± 2.4ms with the same image. That's about an 80x speed up, acheiving my primary goal for this project.

The source code for imgtiger can be found here.