A high-performance, 100% pure Rust implementation of SIXEL graphics encoding and decoding.
SIXEL (Six Pixels) is a bitmap graphics format for terminals, originally developed by DEC for the VT200 series terminals in the 1980s. It allows displaying images directly in terminal emulators that support the format.
Modern terminals with SIXEL support include:
- xterm (with
+sixelbuild option) - mlterm, foot, WezTerm, Contour, ctx, and many more
This repository contains two crates:
icy_sixel - Library
The core Rust library for encoding and decoding SIXEL graphics.
cargo add icy_sixelFeatures:
- High-quality color quantization (Wu's algorithm + Floyd-Steinberg dithering)
- SIMD-accelerated decoder
- Full transparency support
- Configurable pixel aspect ratio and background mode
- No C dependencies
icy_sixel-cli - Command-Line Tool
A CLI for converting images to/from SIXEL and playing animated GIFs.
cargo install icy_sixel-cliCommands:
sixel encode- Convert PNG/JPEG/GIF/WebP to SIXELsixel decode- Convert SIXEL back to PNGsixel animate- Play animated GIFs in the terminal
use icy_sixel::SixelImage;
let rgba = vec![255, 0, 0, 255]; // Red pixel
let sixel = SixelImage::try_from_rgba(rgba, 1, 1)?.encode()?;
print!("{}", sixel);# Display image in terminal
sixel encode image.png
# Play animated GIF
sixel animate animation.gif
# Convert SIXEL to PNG
sixel decode image.six -o output.pngVersion 0.7.0 supports both one-shot decoding with
SixelImage::decode() and incremental decoding with
SixelDecoder::begin_dcs() / feed() / finish(). Both use the same decoding
core; streaming avoids buffering the entire encoded input, but still retains
the growing RGBA canvas. Streaming was introduced in 0.7.0 and is not available in 0.6.x.
Measured on 2026-09-06 with Linux x86_64, AMD Ryzen 9 9950X3D and Rust 1.96.0, after the decoder optimizations for 0.7.0:
| Fixture | Batch (non-streaming) | Streaming, 1-byte chunks | Streaming, 1-KiB chunks | Streaming, 8-KiB chunks |
|---|---|---|---|---|
| Test page | 67.41 µs | 127.87 µs | 68.87 µs | 69.73 µs |
| Beelitz photo | 6.79 ms | 11.35 ms | 6.49 ms | 6.45 ms |
| Transparency | 46.26 µs | 101.94 µs | 47.30 µs | 47.61 µs |
With 1-KiB chunks, streaming latency was within about 5% of batch decoding for these fixtures. Feeding one byte at a time took 1.7–2.2× as long because of per-call overhead. Prefer buffered chunks when available; streaming is useful for consuming incoming terminal data without waiting for the entire DCS sequence. Small apparent streaming wins can reflect CPU scheduling and clock variation, not an inherently faster decoder.
These are Criterion point estimates from the same streaming/* benchmark group
(30 samples, 1-second warm-up, 2-second measurement target). Each case includes a
fresh decoder, allocation, parsing, finalization and image disposal, with embedded
input and no timed file I/O. They compare current APIs, not old and new releases.
See the benchmark documentation for methodology,
historical comparisons and profiling, and the
library README
for streaming usage and termination semantics.
git clone https://github.com/mkrueger/icy_sixel
cd icy_sixel
# Build everything
cargo build --release
# Run tests
cargo test
# Run benchmarks
cargo benchLicensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.