Using LibRaw for RAW files support
Tags: cpp, opensource, devjournal
Published: 2022-09-13 12:16:21

One of the features in Tonfotos our users asked us for some time, is support for "digital negatives" - RAW image files. Even though RAW files are mostly used by professional photographers, while Tonfotos is mostly targeted at general audience, our users encounter RAW files here and there, and would like to work with them just like with any other photo.

And unlike regular image formats (jpeg and others), there is no single standard for RAW files. All leading camera vendors came up with not just one format of their own, but several. For example, Canon started with CRW, then moved on to [CR2](https://tonfotos.com/articles/cr2/), and now uses CR3. So RAW support is definitely one of those features that enables incremental amount of value, that may come at very high cost.

Luckily, there is [LibRaw](https://www.libraw.org/). This is open source library that comes with two types of licenses: LGPL 2.1 and CDDL 1.0. And thanks to latter, it can be freely used even in commercial projects.

Camera models support this library provides is pretty impressive. So far we were able to meet only one case, when user was not completely satisfied - his new Canon camera was not yet supported.

Overall, experience with adding it was pretty smooth. Here are just a few know-how we would like to share in case others may face similar obstacles:

* There is precompiled version of library available for download, but platform support is not that extensive. For example there is no Apple Silicon version for macOS. So we ended up with just adding whole source code of the library to our project, and that solved all platform support issues. No need for separate .dll, everything started working for all our architectures.

* During compilation library generates lots of warnings. Probably we will do some cleanup and submit a PR, but so far time restrictions did not allow us to do so.

* Library is not thread safe by design. Even though it uses classes, for some reason some of the internal codecs rely on global variables. If you plan to use it in several threads, you will need to compile it with TLS support for global variables. Make sure that **LIBRAW_NOTHREADS** is not set in your config (it is set in macOS build by default).

* You will need **LIBRAW_NODLL** define for inclusion of source codes into your application.

* [Here](https://www.libraw.org/docs/API-overview.html) you can find boilerplate code to start playing around with the library.

* There are two ways how you can get dimensions of output bitmap image. Boilerplate code uses **imgdata.sizes**, but there is also **get_mem_image_format()**. And, as we learned the hard way, there is small percentage of cases when their results may differ, which will lead memory exception when you call **copy_mem_image()**. Difference is tiny - width and hight are swapped, but that is enough to calculate wrong stride and go out of allocated memory.

And that seems to be pretty much it. Everything else went pretty smooth. Unfortunately, the list of [applications that use LibRaw](https://www.libraw.org/node/2088) is pretty small, which is sad, since library is great. Probably this is just because people are too lazy to report their usage.

Happy hacking!