[RFC] Enhancing SIXEL with a 1024-Color Palette
Introduction
SIXEL, a bitmap graphics format for terminals, has traditionally been limited to 256 color registers. While libsixel offers an experimental High Color mode (SIXEL_QUALITY_HIGHCOLOR) that bypasses this limit by dynamically updating color registers, I would like to propose an alternative better approach: using dynamic 1024-color palette.
This extended palette offers comparable image quality to High Color mode while providing better compatibility, smaller output sizes, and potentially broader terminal support.
Background: High Color Mode in libsixel (2014)
libsixel’s High Color mode enables 15-bit color (5 bits per RGB channel) by continuously modifying the terminal’s palette registers during output.
This clever hack allows for significantly richer gradients and smoother transitions than the default 256-color limit permits. The mode can be enabled in img2sixel using the -I or --high-color option, and it’s already being used by some advanced users.
However, this method comes with notable trade-offs:
- It relies on terminal support for dynamic palette changes.
- It often results in large SIXEL outputs.
The 1024-Color Palette Approach
Notably, this method allows for adaptive palette selection, optimizing colors based on frequency and distribution in each image. This flexibility may help the 1024-color palette achieve visual quality comparable to that of 15-bit High Color mode.
Visual Comparison
Below is a side-by-side comparison of the same image rendered using:
- A 256-color palette
- A 1024-color palette
- High Color mode (15-bit)
The 256-color version clearly suffers from dithering artifacts — visible as grainy noise. The other two versions appear nearly identical at a glance. In fact, even upon close inspection, it's difficult to distinguish which one offers better quality. (Note: the bottom glitch in the High Color image is likely a bug in mlterm, not a rendering issue.)
Why does the 10-bit (1024-color) image look as good as the 15-bit one? The key lies in palette optimization. Unlike High Color mode, which uniformly truncates colors to 5-bit values, the 1024-color palette can allocate density where it matters most. As a result:
- Gradients in High Color mode can show banding due to uniform quantization.
- Dithering in High Color mode is less effective because the quantization error is limited to 3 bits and doesn't diffuse well.
- The 1024-color palette may introduce slight graininess, but this can actually soften color boundaries and improve perceived image quality.
File Size and Performance
The following benchmarks compare the size of SIXEL output files:
- The 1024-color output is about 30% larger than the 256-color version.
- However, High Color mode output is 2.5× larger than the 1024-color version.
Given that SIXEL images are often transmitted over SSH or processed by resource-constrained decoders, smaller image size provides significant advantages.
Processing speed was also measured by rendering the same sample image 100 times without clipping:
The results show that High Color and 1024-color modes perform at roughly the same speed.
Compatibility and Portability
Despite being available for some time, High Color mode remains poorly supported by terminal emulators. This is due to its reliance on dynamic palette updates, which require specialized internal handling by the terminal.
In contrast, the 1024-color palette approach simply increases the number of static color registers — a much simpler change for terminal developers. In fact:
-
xtermandminttyalready support 1024-color palettes. -
Terminals like mlterm and RLogin have adopted support quickly with minimal effort.
Implementation Status
The 1024-color palette feature is currently under development in the feature-1024-palette branch of saitoha/libsixel.
Notably:
- While there have been minor changes to constants in sixel.h, there are no modifications to function signatures or the public API structure.
- ABI compatibility has been preserved.
- As a result, the impact on applications using libsixel is expected to be minimal.