CLI tool
dnglab/dnglab avatar
dnglab/dnglab

DNGLab: converting camera RAW files to DNG

Camera RAW to DNG file format converter

700 stars125 forksRustLGPL-2.1

At a glance

What is it?
DNGLab is an LGPL 2.1 licensed Rust command line tool that converts camera RAW files into the Digital Negative format, covering more than twenty five raw formats from ARRI and Canon to Sony and Phase One, with a fuzzed parser and an analyzer that can dump the metadata and the checksums of a file. The judgement is that the honesty about its own state is unusual, and that the format support, rather than the DNG writing, is where the work went.
Who is it for?
DNGLab fits a photographer who wants their RAW files in a documented container rather than in a vendor format, because the tool reads the formats the cameras actually write and writes a DNG with lossless compression, and because the analyze command lets you check what the parser actually saw in a file before you trust it.
Can I use it commercially?
Yes, with conditions. LGPL-2.1 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A converter that says it is in alpha

DNGLab is a command line tool for converting camera RAW files to the Digital Negative format, and the readme opens with the caveat that matters most for an adopter.

It is currently in alpha state, so you should not expect a polished and bug free application, and bugs should be reported in the issue tracker. That sentence is unusual in a readme, and it is the kind of thing that saves an afternoon when a conversion comes out wrong, because you know in advance that the tool is a work in progress rather than something with a support contract behind it.

The second caveat is about the library underneath. The Rawler crate is published to crates.io, but the API is not yet stable, so Rawler does not follow semantic versioning. That is a clear signal to a Rust developer: use it inside an application, do not build a public library on top of it and do not expect a patch release to keep your code compiling.

The project is LGPL 2.1 licensed, written in Rust, and the release history is a 0.7 line through the end of 2025 and into 2026, with 0.7.1 on 2025-10-03, 0.7.2 on 2026-02-26 and 0.8.0 on 2026-08-30. The last push was on 2026-10-18, and the project also has a Matrix room alongside the issue tracker.

Twenty five raw formats, and one special case

The supported formats table is the most useful thing in the readme, and it lists twenty five format names across sixteen manufacturers.

ARRI is there with ARI. Canon has CR3, CR2 and CRW, with the CR3 entry linking to a separate document about the state of that format. Epson has ERF, Fujifilm RAF, Hasselblad 3FR, Kodak with KDC, DCS and DCR, Leaf with IIQ and MOS, Mamiya MEF, Minolta MRW, Nikon with NEF and NRW, Olympus ORF, Panasonic and Leica RW2, Pentax and Ricoh PEF, Phase One IIQ, Samsung SRW, and Sony with ARW, ARQ, SRF and SR2.

Every row is marked as supported, so the support is about the container format rather than about a feature matrix, and the interesting exception is the note on the Sony ARQ row. ARQ is the pixel shift format produced by Imaging Edge, and the remark says it is converted to RGB, which is the one place where the tool does not simply repackage the sensor data.

The camera list itself lives in a separate document, SUPPORTED_CAMERAS.md, and the readme points there for the list of supported cameras, so the models that are known to work are tracked separately from the formats that are parsed.

The distinction between those two lists is a useful one for a reader, because a format can be parsed and a camera can still produce a file the tool mishandles, and the second list is where that would be recorded.

The DNG side is deliberately narrow

The list of supported DNG features has one entry, and it is the important one: DNG lossless compression, which is LJPEG-92.

That is a much smaller promise than a full raw developer would make. A DNG can carry far more, the various uncompressed and lossless codecs, the various preview encodings, the raw data laid out in a dozen different ways, and the per maker notes that some software relies on. This tool writes one of them, the lossless one, and does it for every input format.

The convert options in the help text show the shape of what can be varied. The artist tag can be set. The compression can be lossless or uncompressed. The DNG default crop can be best, active area or none, which is the question of which rectangle the renderer should treat as the image. The preview image and the thumbnail can be included or left out, and the raw file itself can be embedded in the DNG or not. The image index selects a specific image in a container or all of them, the LJPEG-92 predictor can be chosen from one to seven, and the input directory can be processed recursively.

The defaults are sensible and worth knowing, because they are the opposite of what a photographer might assume. The crop defaults to best, the preview and the thumbnail are included by default, the raw is embedded by default, and the compression is lossless.

Embedding the raw is the decision that makes the output file large, and it is also what makes it recoverable, since the original sensor data is inside the DNG even if the DNG itself is later discarded.

Two subcommands, and the analyzer is the interesting one

The tool has two subcommands, and the second is more revealing than the first.

Convert is the obvious one. It takes an input file or directory and an output file or an existing directory, and the readme gives two examples, a single file and a whole directory:

code
dnglab convert IMG_1234.CR3 IMG_1234.DNG
dnglab convert ~/DCIM/100EOS ~/filmrolls/photos-france

The analyze subcommand takes a single file and writes what the parser found out to standard output, and the options are what make it useful rather than a curiosity. There is a metadata flag that writes the metadata, and a JSON flag that formats the metadata as JSON, which is the difference between reading it and piping it into something else.

Then there are the pixel level options. The raw pixel flag writes the uncompressed raw pixel data, and the full pixel flag writes the uncompressed full pixel data. The preview pixel flag does the same for the preview. And there are two checksum flags, one for the raw pixels and one for the preview, each writing an MD5 checksum.

So the analyzer is a way of asking the parser what it thinks a file contains, and then checking that against an independent implementation. The checksum flags are the reason it matters: if your converter and another tool disagree about the pixels, the checksums tell you immediately, and if they agree, the conversion is likely sound.

For a project in alpha, that is a much better debugging position than a screenshot of a wrong image.

A deb, a single binary, or a cargo build

There are three ways to get the tool, and the readme is clear about which is which.

There are pre-built binary packages for each release, in the asset section under the latest release. The.deb packages are for Debian based systems in both amd64 and arm64, and they install with dpkg. For other systems there is a single binary file, and the readme's example runs it directly, converting a Canon raw file into a DNG.

Windows is not officially supported, and the readme says so, but the release assets do contain a zip with a pre-built Windows binary, with the warning that the build is untested. That is a reasonable arrangement for a project in alpha, and the warning is what makes it usable, because you know not to rely on it.

Building from source needs the Rust toolchain, and the sequence is the standard three commands:

code
git clone https://github.com/dnglab/dnglab.git
cd dnglab
cargo build --release

The binary then sits at target/release/dnglab, and the fact that the readme names the path explicitly is the kind of detail that saves a search through the target directory.

The build is a Cargo workspace with a release profile that optimises for speed, an opt level of three with the overflow checks turned off and the debug information stripped, and the lint configuration treats the unwrap macro as a warning at the workspace level, which is the right setting for a parser that has to survive malformed input.

Three crates, and a library that does not promise stability

The Cargo workspace has three members, and the split tells you the shape of the project.

There is bin/dnglab, which is the command line application, rawler, which is the library that reads and writes the raw formats, and embedftp, which is a separate member whose purpose the readme does not spell out but whose name suggests embedding an FTP server, and in a project about photographs that is likely the piece that fetches files from a camera or a server.

Rawler is the interesting one, because it is the part that other people would want to use. The readme says it is now published to crates.io, and immediately follows with the warning that the API is not yet stable and therefore does not follow semantic versioning. That is an unusual, explicit admission, and a useful one, because the alternative is a 0.x version number that implies the same thing more quietly.

The workspace also carries the lint configuration, with the unwrap macro warned and the collapsible if check allowed, which is a sensible pairing for a codebase that parses untrusted files, since the allow exists for the places where the nesting is genuinely clearer than the flattened form.

The repository also has the supporting files a parser project needs, a scripts directory, a justfile, a rustfmt configuration, an AUTHORS file, a document about contributing test samples, and two scripts for regenerating the test data, one of them a Python program called rawdb_regen_tests.py, which suggests the test corpus is built from real camera files rather than only from synthetic ones.

The parser is fuzzed, and the fuzzing is scripted

The justfile has more in it than a justfile usually does, and the extra part is a fuzzing setup.

The ordinary recipes are there, a fix target that runs clippy with its own fix flag and then formats the workspace, a format target, and a check target that runs clippy across the workspace with warnings promoted to errors and then verifies the formatting without changing it.

The fuzzing is the part worth reading. The comments explain the setup, which is to install cargo-fuzz and a nightly toolchain, and the usage line shows that a fuzz run is invoked by target name, with a duration in seconds, a number of jobs, a corpus path, a maximum length of sixty five thousand five hundred and thirty six bytes and an RSS limit of twenty thousand megabytes.

The target defaults to fuzz_decode_full, which is the whole-file decoder, and the runner sets an AddressSanitizer option, allocator_may_return_null, so that a fuzz case hitting a huge allocation returns null rather than aborting the process, which is what lets the fuzzer explore the paths that allocate.

There is also a fuzz-all recipe, which lists the targets in the fuzz directory and runs each of them in turn with the same settings, and a fuzz-list recipe to show what is there. Running every target rather than one is the point, because a parser has several entry points and each is a separate way in for malformed data.

The combination of a fuzzed parser, a test corpus regenerated from real files and an analyzer that can dump checksums is a project that is trying to be trustworthy while it is young, which is the right order to do things in.

Editorial conclusion

DNGLab fits a photographer who wants their RAW files in a documented container rather than in a vendor format, because the tool reads the formats the cameras actually write and writes a DNG with lossless compression, and because the analyze command lets you check what the parser actually saw in a file before you trust it. It is the wrong choice if you need the features of a full raw developer, since the DNG side supports only lossless compression and a small set of options, and it is the wrong choice if you need a supported tool, because the project says outright that it is in alpha and expects to have bugs. Before you convert an archive with it, run the analyzer over a copy of one file, and keep the original RAW, because the embedded raw and the preview images are options you can turn off.

Frequently asked questions

What does DNGLab do?

It is a Rust command line tool that converts camera RAW files into the Digital Negative format. The convert subcommand takes a file or a directory and writes a DNG, and the analyze subcommand reports what the parser found in a file, with options for the metadata, the pixel data and MD5 checksums of the raw and preview pixels.

Which camera RAW formats are supported?

Twenty five format names across sixteen manufacturers, including ARRI ARI, Canon CR3, CR2 and CRW, Fujifilm RAF, Hasselblad 3FR, Nikon NEF, Olympus ORF, Phase One IIQ and Sony ARW, ARQ, SRF and SR2. The Sony ARQ pixel shift format is converted to RGB rather than copied.

Is DNGLab ready to use?

The readme says it is currently in alpha state and that you should not expect a polished and bug free application, and it asks for bugs to be reported in the issue tracker. The underlying Rawler crate is on crates.io but its API is not stable and does not follow semantic versioning.

How do I install DNGLab?

Pre-built packages are in the assets of the latest release, a .deb for Debian based systems in amd64 and arm64 installed with dpkg, or a single binary for other systems. Windows has an untested zip in the release assets. From source it is a clone, a cd and a cargo build --release, and the binary ends up at target/release/dnglab.

Official sources

  1. dnglab/dnglab on GitHub
  2. Issues
  3. License: LGPL-2.1
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dnglab-dnglab.svg)](https://hysenlabs.com/projects/dnglab-dnglab)

Was this useful?