# libcimbar: transferring files via animated barcodes at 850 kilobits per second

> libcimbar encodes files into a sequence of colored high-density barcodes (cimbar format) that can be displayed on a screen and decoded by a smartphone camera. No internet or wireless is needed; data travels through the air via light and a lens.

**sz3/libcimbar** — Optimized implementation for color-icon-matrix barcodes

- Repository: https://github.com/sz3/libcimbar
- Website: https://cimbar.org
- Stars: 6,493 · Forks: 473
- Language: C++
- License: MPL-2.0
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/sz3-libcimbar

## An experimental barcode format for offline data transfer

libcimbar is a C++ implementation of cimbar, an experimental high-density 2D barcode format designed for air-gapped data transfer. An air-gapped device has no network, wireless, or physical connection to other devices; data travels only through the camera lens as animated barcodes on a screen. The encoder displays a sequence of frames on a monitor or smartphone screen, each frame a grid of colored tiles. The decoder is an Android application that watches the screen through the phone camera and decodes the barcodes in real time. No internet, Bluetooth, NFC, or USB is used; all data transmission happens through the optical channel. The system sustains speeds of 850 kilobits per second (about 106 KB/s) using only a computer monitor and a smartphone camera. Last push was on 2026-09-26, three days ago, indicating active maintenance. Latest release was v0.6.8 on 2026-08-26, followed by v0.6.7c in July and v0.6.5 in May.

## How cimbar encodes and decodes data

cimbar is a high-density 2D barcode. Data is stored in a grid of colored tiles; bits are encoded based on which tile is chosen and which color is chosen to draw that tile. Reed Solomon error correction is applied to the data to account for the lossy nature of video decoding from the camera, with sub-1% error rates expected and corrected. The barcode density and color scheme are optimized for reliable decoding through camera optics.

libcimbar, the optimized C++ implementation, layers a protocol on top of the barcode format. Files are compressed using zstd compression, then encoded using fountain codes from the wirehair library. This approach allows files up to 33 MB (after compression) to be split into a series of cimbar barcode frames. Fountain codes ensure that any sufficient subset of frames can reconstruct the file, regardless of order or loss. Crucially, frames can be received out of order, and some can be corrupted or missing; once enough distinct frames are decoded successfully, the file will be reconstructed and decompressed. This resilience is essential for optical decoding, where lighting, camera focus, angle, and monitor refresh rates all affect the quality of each frame captured by the phone camera.

## Building and running the encoder and decoder

On Linux, install dependencies:

```bash
sudo apt install libopencv-dev libglfw3-dev libgles2-mesa-dev
```

Then build with CMake:

```bash
cmake .
make -j7
make install
```

The README notes that large input files may consume disk space with PNG outputs. To encode a file:

```bash
./cimbar --encode -i inputfile.txt -o outputprefix
```

To decode a series of PNG images:

```bash
./cimbar outputprefix*.png -o /tmp
```

Or decode from stdin:

```bash
echo outputprefix*.png | ./cimbar -o /tmp
```

To encode and animate barcodes to a window:

```bash
./cimbar_send inputfile.pdf
```

Alternatively, use the web encoder at https://cimbar.org or download the offline HTML file from the releases page.

## Encoder portability via WebAssembly and offline use

The encoder compiles to WebAssembly (WASM) and asmjs, allowing it to run in any modern web browser without server-side processing. The web app is available at https://cimbar.org. For offline use, you can download the latest release of `cimbar_js.html` from the releases page, save it locally, and open it in a web browser. You can also install cimbar.org as a progressive web app (PWA) on your device for offline-first use without needing to redownload the app. The decoder is an Android application (cfc) available on GitHub that uses the phone camera to capture frames and decode them in real time with the corresponding cimbar protocol.

## Build requirements and platform support

libcimbar is written in C++ and developed/tested on amd64 Linux, arm64 Android (decoder only), and emscripten WASM (encoder only). It probably works on other platforms but the primary development is for Linux and Android. External dependencies required before building are OpenCV and GLFW (plus OpenGL ES headers). Many other dependencies are bundled in the source tree: catch2 for testing, fmt for formatting, zstd for compression, wirehair for fountain codes, base, concurrentqueue, cxxopts, intx, libcorrect, libpopcnt, PicoSHA2, and stb_image. On Ubuntu/Debian Linux, install dependencies via `sudo apt install libopencv-dev libglfw3-dev libgles2-mesa-dev` before running cmake. Windows is supported on a best-efforts basis using MSVC and vcpkg, which installs OpenCV, GLFW, and ANGLE (a Windows OpenGL compatibility layer) during configuration. The build process uses CMake with a provided vcpkg.json and supports parallel compilation with `-j` flag for faster builds.

## Fountain codes, compression, and large files

libcimbar uses fountain codes from the wirehair library, a technique that allows a file to be split into many encoded blocks, with the property that any sufficient subset of blocks can reconstruct the file. This is crucial for optical decoding, where some frames may be unclear or missed. Compression via zstd reduces the input file size before encoding, directly increasing the speed at which a file can be transferred; a 1 MB file compressed to 0.5 MB saves transfer time proportionally. The library supports files up to 33 MB after compression. A community tool, cimbar-bigfile, extends this by splitting very large files (100+ MB) into multiple parallel encoding streams, each 10-15 MB per stream, and provides a manifest.json for SHA256-verified reassembly without requiring changes to libcimbar or cfc.

## Airgapped networks, slow transfer, Android-only decoder

libcimbar is built for scenarios where no network is available or where using network is not acceptable: physically isolated lab environments, secure facilities, situations where radio transmission is not allowed. The 850 kbps speed is respectable for optical transmission but is much slower than a wired network; a 100 MB file would take more than 13 minutes to transfer. The decoder is Android-only; there is no iOS decoder app. Decoding requires clear line-of-sight between the screen and the phone camera, appropriate lighting, and physical proximity. The format is experimental; DETAILS.md and PERFORMANCE.md documents explain the implementation details and measured performance limits. The project includes a community tool, cimbar-bigfile, which wraps the encoder to split very large files (100+ MB) into multiple parallel streams of 10-15 MB chunks each, with a manifest for SHA256-verified reassembly. This extension does not require changes to libcimbar or cfc. The repository is licensed under MPL-2.0, allowing distribution and modification under the terms of the Mozilla Public License.

## Conclusion

Adopt libcimbar if you need to transfer files between air-gapped devices (no network connection, no wireless), or if you want to explore high-density barcode formats. Skip it if you need standard QR codes or if you have any network connectivity available, which will be faster and more reliable. To verify, test the encoder at https://cimbar.org with a small file and decode with an Android phone using the cfc app on the same local network or offline.

## FAQ

### How does libcimbar transfer data without internet or wireless?

The encoder displays animated barcodes on a screen, and the decoder smartphone app reads them through its camera. All data is transmitted through the optical channel.

### What is the transfer speed with libcimbar?

Up to 850 kilobits per second (about 106 KB/s) using a computer monitor and smartphone camera.

### Can I decode libcimbar barcodes on an iPhone?

No. The decoder is only available as an Android application (cfc). There is no iOS version.

## Sources

- [License: MPL-2.0](https://github.com/sz3/libcimbar/blob/master/LICENSE)
- [Project website](https://cimbar.org)
- [README](https://github.com/sz3/libcimbar/blob/master/README.md)
- [Releases](https://github.com/sz3/libcimbar/releases)
- [sz3/libcimbar on GitHub](https://github.com/sz3/libcimbar)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sz3-libcimbar
