icy_sixel
A high-performance, 100% pure Rust implementation of a SIXEL encoder and decoder.
I wanted a pure Rust implementation to simplify deployment of my cross-platform applications. In version 0.4.0, I rewrote the encoder using quantette, a high-quality color quantization library licensed under MIT/Apache-2.0. It uses Wu's algorithm with Floyd-Steinberg dithering for excellent results.
The decoder is a clean-room implementation based on the SIXEL specification, with SIMD optimizations for maximum performance.
Features
- SIXEL Encoder: High-quality color quantization with quantette (Wu's algorithm + Floyd-Steinberg dithering)
- SIXEL Decoder: Clean-room implementation with RGBA output and SSE2 SIMD acceleration
- Transparency Support: Full alpha channel handling in both encoder and decoder
- Pure Rust: No C dependencies, easy to build and deploy
- Cross-platform: Works on Linux, macOS, and Windows
Installation
Add this to your Cargo.toml:
[]
= "0.4"
Usage
Encoding an Image to SIXEL
use ;
// RGBA image data (4 bytes per pixel)
let rgba = vec!;
let options = default;
let sixel = sixel_encode?;
print!;
Encoding with Custom Options
use ;
let options = EncodeOptions ;
let sixel = sixel_encode?;
Decoding SIXEL to Image Data
use sixel_decode;
let sixel_data = b"\x1bPq#0;2;100;0;0#0~-\x1b\\";
let image = sixel_decode?;
// image.rgba contains RGBA pixel data (4 bytes per pixel)
// image.width and image.height contain dimensions
CLI Tool
The crate includes a command-line tool for encoding and decoding:
# Install the CLI
# Encode a PNG to SIXEL (outputs to stdout by default)
# Encode with custom settings
# Read from stdin
|
# Decode SIXEL to PNG
# Decode from stdin
|
Architecture
Encoder
The encoder uses quantette for high-quality color quantization with Wu's algorithm and Floyd-Steinberg dithering. This produces excellent results, especially for images with gradients or complex color distributions.
Decoder
The decoder is a clean-room implementation derived from the SIXEL specification:
- Returns RGBA buffers (4 bytes per pixel) for easy integration with graphics libraries
- SIMD-accelerated horizontal span filling on x86/x86_64 (SSE2)
- Optimized with color caching and loop unrolling
- Comprehensive bounds checking prevents buffer overflows
Showcase
Original image for reference (596×936 pixels, 879 KB PNG):

Color Palette Comparison (Wu quantizer, full diffusion)
| Colors | SIXEL Size | Result |
|---|---|---|
| 256 | 1.1 MB | ![]() |
| 16 | 440 KB | ![]() |
| 2 | 105 KB | ![]() |
Dithering Comparison (Wu quantizer, 16 colors)
| Diffusion | SIXEL Size | Result |
|---|---|---|
| Off (0.0) | 420 KB | ![]() |
| Full (0.875) | 440 KB | ![]() |
Quantizer Comparison (256 colors, full diffusion)
| Method | SIXEL Size | Result |
|---|---|---|
| Wu | 1.1 MB | ![]() |
| K-means | 1.3 MB | ![]() |
Benchmarks
Performance measurements on the test image (596×936 pixels, beelitz_heilstätten.png):
Encoder Performance
| Benchmark | Time |
|---|---|
| Default (Wu, 256 colors, full diffusion) | 41.7 ms |
Quantizer Comparison
| Quantizer | Time | Notes |
|---|---|---|
| Wu | 41.8 ms | Fast, default |
| K-means | 88.1 ms | 2.1× slower |
Color Count Impact
| Colors | Time |
|---|---|
| 256 | 42.0 ms |
| 16 | 16.3 ms |
| 2 | 10.8 ms |
Diffusion Strength Impact
| Diffusion | Time |
|---|---|
| Off (0.0) | 21.3 ms |
| Low (0.3) | 31.7 ms |
| Medium (0.5) | 34.1 ms |
| Full (0.875) | 41.9 ms |
Decoder Performance
| Benchmark | Time |
|---|---|
| Simple SIXEL | 151 ns |
| Complex SIXEL | 677 ns |
| Repeated patterns | 1.46 µs |
Scaling with Size
| Bands | Time |
|---|---|
| 10 | 1.3 µs |
| 50 | 15.9 µs |
| 100 | 52.6 µs |
| 200 | 209 µs |
Color Palette Size
| Colors | Time |
|---|---|
| 1 | 150 ns |
| 4 | 485 ns |
| 16 | 2.0 µs |
| 64 | 12.4 µs |
Benchmarks run with cargo bench using Criterion on Linux.
License
Licensed under the Apache License, Version 2.0 — see LICENSE for details.




