# Nibnib: Image Compression Optimized for Extreme Decompression Speed

A high-performance image format designed for resource-constrained microcontrollers like the RP2350.

- **Source:** [Hacker News](https://news.ycombinator.com)
- **Published:** 2026-10-30
- **Topic:** [Software & Engineering](https://brifing.si/c/engineering)
- **Original article:** <https://github.com/raphlinus/nibnib>
- **On Brifing:** https://brifing.si/s/c09133d7-ab70-4b68-97f3-472bd18c464d

## Microcontroller Performance Constraints

Nibnib was developed as an experimental image format specifically for the RP2350 microcontroller. The primary design goal was to fit within a strict budget of approximately 6 cycles per pixel. This allows for essential operations like pixel fetching, palette lookup, and line buffer storage without requiring significant additional processing overhead or memory.

## Delta-Based Palette Mechanism

Unlike standard palette images that store absolute color values, Nibnib stores deltas. This approach significantly improves quality in soft regions by calculating differences rather than fixed points. The format achieves 4bpp compression by decoding two pixels simultaneously from a single input byte, ensuring high throughput for hardware with limited computational resources.

## Deterministic Decoding Logic

The decompression process is strictly deterministic and straightforward. It functions by doubling the last decoded pixel and adding a 32-bit value retrieved from the palette. This operation yields two 16-bit RGB 565 pixels. The simplicity of this inner loop allows it to run efficiently on low-power hardware without complex branching or logic.

## Asymmetric Encoding Complexity

Nibnib features an asymmetric design where the encoder is significantly slower than the decoder. While the decoder is optimized for speed, the encoder performs an extensive search through possible palette entries and codewords. This trade-off is intentional, as the format is intended for pre-processed assets rather than real-time encoding on the device.

## Error Diffusion and Palette Selection

The current encoder uses a greedy search to minimize error, distributing it via Floyd-Steinberg weights. It evaluates all 256 palette entries to find the best match for two pixels simultaneously. By prioritizing the sum of errors, the algorithm accounts for the human visual system's higher sensitivity to lower spatial frequencies during the compression.

## Addressing Sharp Edge Artifacts

Current implementations exhibit trailing artifacts to the right of sharp edges due to the greedy search strategy. Future improvements could involve bidirectional encoding or boustrophedon scanning to mitigate these visual defects. Because the addition step is effectively invertible, these changes would enhance visual quality without requiring any modifications to the existing decoder.

## Format Structure and Metadata

The file format is intentionally minimal, consisting of 2-byte width and height headers followed by 256 32-bit palette entries. Each row begins with two raw RGB 565 pixels, followed by palette indices. There is no additional metadata, as the format is designed for tight integration with specific hardware decoders rather than general archival.

## Future Optimization Potential

While the current version uses a fixed palette structure, adaptive palette selection based on input images remains a key opportunity for quality improvement. Developers can also refine the Gaussian-based palette generation to better balance sharpness and noise. All these enhancements remain compatible with the current decoder, preserving the format's core performance benefits.

## Sources covering this story

- https://github.com/raphlinus/nibnib — 

---

_Summary written by Brifing from the original reporting. Copyright in the original article belongs to its publisher; read the full piece at the link above._
