dlib: Past, Present and Future
As you may know, my main D project is dlib, a general purpose library for D language. It contains such functionality as linear algebra objects, computational geometry algorithms, I/O streams and filesystem abstraction, image and audio processing.
dlib has rather interesting early history which is rooted in my old C++ projects. My first general purpose library was Sparx, which was written in C++ in 2010–2011. After switching to D, I continued using it via C interface and Derelict binding, but it wasn’t very convenient, so I decided to write a native D replcement for some of its parts. Eventually this led to creation of dlib.math and dlib.image, first packages of dlib. The name coincidence with dlib for C++ is purely accidental. It was actually a temporary codename that stuck with a project, I decided not to change it.
Sparx served mainly as an asset loader for games, it supported PNG, JPEG, JPEG2000, TGA, BMP, DDS, OBJ, MD5. Today its influence is not so obvious, but some directly ported stuff from Sparx still exist — image processing code, image decoders, various math and geometry functions to name a few.
Other early influences include code by David Henry, especially his minimalistic image loaders that inspired dlib’s PNG, TGA and BMP decoders. Though now dlib decoders have very little in common with them after many years of refactoring. JPEG decoder was written entirely from scratch using various articles, mainly “Designing a JPEG Decoder” by Calvin Hass. dlib.math.vector and dlib.math.matrix were heavily inspired by David Henry’s Mathlib for C++. They are not direct ports, but still have a lot in common. Key differences include templated dimensions (Mathlib’s dimensions were hardcoded: only Vector3 and Matrix4x4), column-major layout for matrices instead of row-major, optimized matrix inversion, vector swizzling and many additional functions.
As an Open Source project, dlib started on September 28, 2012. It was initially hosted on Google Code. At the time it consisted of dlib.core, dlib.image, dlib.math, dlib.geometry, and dlib.functional. It moved to GitHub in 2013, which resulted in many contributions from the community: Martin Cejp did a great job of implementing I/O streams and abstract file system (dlib.core.stream, dlib.filesystem), Eugene Wissner wrote excellent memory allocators (dlib.memory) and the networking package (dlib.network), Nick Papanastasiou wrote dlib.math.combinatorics, Vadim Lopatin helped to improve PNG decoder, Roman Chistokhodov and Andrey Penechko made lots of bugfixes. Special thanks to Roman for improving BMP and TGA support, as well as for valuable advices.
In 2015, I began to rewrite some features to support manual memory management. Unfortunately, it turned out that making dlib a @nogc
library and retain backward compatibility is not possible, because core parts of dlib were written long before @nogc
. Instead I decided to write an additional API layer that delegated memory management to the user, but worked with the same old interfaces (such as SuperImage
). Main drawback is that GC-free code in dlib is not compatible with @nogc
libraries. However, strict independence from Phobos and GC, which is what ensured by betterC
and @nogc
, is not the goal of this project, and never was. dlib’s memory allocators are solely for determinism and programmer’s control over resources.
In 2016, dlib.audio appeared. It is still in early stages of development, including only basic audio synthesis functions and WAV import and export. It is based on similar principles as dlib.image and currently supports bit depths 8 and 16 (signed and unsigned), as well as arbitrary sample rate and number of channels. In principle, it can be used as a backend for more complex audio processing library.
What is dlib today? I define it as a collection of libraries for writing graphics-intensive applications. It is mostly used in game development and scientific research, as intented. Some interesting use cases include RIP, scientific image analysis library, and rengfx, a game engine based on raylib. In 2020 dlib package in Dub repository achieved more than 1500 downloads per month, which made it hit the top 20 packages for a while!
Unfortunately, I cannot say that D took off over last decade, and my work became something more than just a hobby project. It is recognized in D community, but D itself is still a very niche language which is used mainly by enthusiasts. So I no longer have hopes that dlib will be ever used in mainstream game development, and it’s unlikely that I’ll add more substantial features to it. It is already nice as it is, a minimalistic self-contained framework for experiments and pet projects.
Currently I’m working on preparing 1.0 release, after which I’ll concentrate on my other projects. dlib 1.0 will be a huge milestone, and it’s not clear how exactly dlib should be improved further. There’s a sandbox branch for dlib 2 where I test some ideas, but it is still in early stages of its lifetime. One obvious thing is that dlib 2 should be betterC-compliant, and its core part should be isolated to a separately usable library. Idiomatic dlib 0.x/1.0 API may be implemented on top of this core, or it may be fully rewritten to support @nogc
.