The Image Editor Software Landscape
I, like most other photographers, use Lightroom to edit the RAW photos we take but I am not happy with how sluggish the editing was on my laptop. I have a Microsoft Surface Book 2 with a laptop-spec'ed NVIDIA GeForce GTX 1060 but the 15" 3240×2160 (260 PPI) screen is a lot of pixels to process. Because of this, I stick to a lower DPI 1080p external monitor. The issue is, this guy is is not nearly as vibrant and the software is still not snappy. Most of the time I will edit an image on this monitor and when I display it on another (color correct) display it looks over saturated.
I checked out darktable v5 since it seems to be a competitive open source photography workflow application only to find out it is even slower. After looking to see if there was anything i could reconfigure to help, I stumbled upon ansel and there in the README I found out why it was slow. I gave ansel, the highly opinionated and optimized fork of darktable, a try and it was so much snappier! It was a lot less feature-rich though and because of this, I went back to Lightroom.
I can do better, for sure, no doubt
The awful UI responsiveness did not make any sense to me. Video games seem to be able to run amazing graphics pipelines at 120fps, so what was the deal with the photo edit pipeline? Getting pretty mad I got my testosterone pumping decided to give it a swing and whip up my own image editor prototype.
Tech | Description |
---|---|
OpenCL | Library for running parallel computation on various hardware |
LibRaw | C++ library for loading raw images like .NEF (Nikon) and .CR3 (Canon) |
cimgui | immediate mode UI library |
sokol | Library for managing window and graphics pipelines on windows/mac/linux |
vlang | Easy to learn, garbage collected language that transpiles to C |
OpenCL is the same method darktable does compute so it would be a good choice if I wanted to study their compute functions for my use. I could write this is C like darktable but I really didn't want to handle my own memory alloc/dealloc, strings, and compilation management.
I used LibRaw because it has a raw image post-processor. darktable uses rawspeed by default but also seems to utilize LibRaw. I opted for LibRaw since it has a builtin RAW data postprocessing like dcraw with raw2image()
seen in this example which will make my prototyping quicker, even though the library is not intended to be used this way.
cimgui and sokol go hand-in-hand for making graphical desktop applications.
I was playing around with vlang at the time and it was so easy to lean and get going with it, it was an obvious choice since it integrates with existing C libraries relatively easily with c2v wrapper function. It also has a library called vsl for interfacing with OpenCL, though it needed some fixing.
All of this combined renders PIE: Peyton's Photo Editor
https://github.com/phcreery/imageeditor
It has extremely limited feature set at the moment, but it has multi-threaded image loading, processes an entire 24.1-megapixel .NEF from a Nikon D7100 at decent speed (sub 1 second) in an un-optimized CL/CPU pipeline. It has absolutely zero stutter zooming and panning images. The best part is, the edit pipeline is running on the same thread as the UI, in a garbage collected runtime, and it is still more satisfying to use than darktable. Once I run it on a separate thread, there should be no interactivity hangups!
Conclusions
I would like to play with OpenMP for multi-processing atr some point. It looks very versatile. If I were to continue on this journey though, I would continue on in Rust as it is a much more sensible language for performance and community support reasons. The probability of that happening is pretty slim though since it takes a lot of work and there is a lot of science behind photo editing.
If I were to play with image editing software again, I really should contribute to something like vkdt since it is also GPU-based interface like PIE and already has a lot of modules built up.